直接上效果图
代码
<template>
<view class="container">
<!-- 签名画布 -->
<view class="canvas-container">
<canvas
canvas-id="signCanvas"
class="sign-canvas"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
></canvas>
</view>
<!-- 操作按钮 -->
<view class="button-group">
<button @click="clearCanvas" class="btn">清除</button>
<button @click="saveSignature" class="btn">保存签名</button>
</view>
<!-- 保存的签名预览 -->
<view class="preview" v-if="imagePath">
<image :src="imagePath" mode="widthFix"></image>
</view>
</view>
</template>
<script>
export default {
data() {
return {
ctx: null, // canvas 上下文
points: [], // 存储绘制点
isDrawing: false, // 是否正在绘制
imagePath: '' // 保存的签名图片路径
}
},
onReady() {
// 初始化canvas上下文
this.ctx = uni.createCanvasContext('signCanvas', this);
// 设置画笔样式
this.ctx.setStrokeStyle('#000000');
this.ctx.setLineWidth(4);
this.ctx.setLineCap('round');
this.ctx.setLineJoin('round');
},
methods: {
// 触摸开始
handleTouchStart(e) {
this.isDrawing = true;
const startX = e.touches[0].x;
const startY = e.touches[0].y;
this.points = [{x: startX, y: startY}];
// 开始新路径
this.ctx.beginPath();
this.ctx.moveTo(startX, startY);
},
// 触摸移动
handleTouchMove(e) {
if (!this.isDrawing) return;
const moveX = e.touches[0].x;
const moveY = e.touches[0].y;
this.points.push({x: moveX, y: moveY});
// 只保留最近的两个点用于绘制线段
if (this.points.length > 2) {
const lastTwoPoints = this.points.slice(-2);
this.ctx.moveTo(lastTwoPoints[0].x, lastTwoPoints[0].y);
this.ctx.lineTo(lastTwoPoints[1].x, lastTwoPoints[1].y);
this.ctx.stroke();
this.ctx.draw(true);
}
},
// 触摸结束
handleTouchEnd() {
if (this.points.length < 2) {
// 如果只有一个点,画一个点
const point = this.points[0];
this.ctx.arc(point.x, point.y, 2, 0, 2 * Math.PI);
this.ctx.fill();
this.ctx.draw(true);
}
this.isDrawing = false;
this.points = [];
},
// 清除画布
clearCanvas() {
this.ctx.clearRect(0, 0, 10000, 10000);
this.ctx.draw(true);
this.imagePath = '';
},
// 保存签名
saveSignature() {
uni.canvasToTempFilePath({
canvasId: 'signCanvas',
success: (res) => {
this.imagePath = res.tempFilePath;
uni.showToast({
title: '签名保存成功',
icon: 'success'
});
// 这里可以添加将签名上传服务器的代码
// this.uploadSignature(res.tempFilePath);
},
fail: (err) => {
console.error('保存签名失败:', err);
uni.showToast({
title: '保存签名失败',
icon: 'none'
});
}
}, this);
},
// 上传签名到服务器(可选)
uploadSignature(tempFilePath) {
uni.uploadFile({
url: '你的上传接口地址',
filePath: tempFilePath,
name: 'signature',
success: (uploadRes) => {
console.log('上传成功', uploadRes);
},
fail: (uploadErr) => {
console.error('上传失败', uploadErr);
}
});
}
}
}
</script>
<style lang="scss" scoped>
.sign-canvas{
width: 100vw;
height: 70vh;
}
</style>