vue实现手写签名
实现手写签名的基本思路
在Vue中实现手写签名功能,通常需要借助HTML5的Canvas API来捕获用户的绘图操作。核心步骤包括创建画布、监听鼠标/触摸事件、记录轨迹并渲染。
核心代码实现
安装依赖(如需要保存为图片):
npm install html2canvas
组件模板部分:
<template>
<div class="signature-pad">
<canvas
ref="canvas"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
@touchstart="startDrawing"
@touchmove="draw"
@touchend="stopDrawing"
></canvas>
<button @click="clearCanvas">清除</button>
<button @click="saveSignature">保存</button>
</div>
</template>
脚本部分:
<script>
import html2canvas from 'html2canvas';
export default {
data() {
return {
isDrawing: false,
lastX: 0,
lastY: 0,
};
},
mounted() {
this.setupCanvas();
},
methods: {
setupCanvas() {
const canvas = this.$refs.canvas;
const ctx = canvas.getContext('2d');
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
ctx.strokeStyle = '#000';
ctx.lineWidth = 2;
ctx.lineCap = 'round';
},
startDrawing(e) {
this.isDrawing = true;
const canvas = this.$refs.canvas;
const rect = canvas.getBoundingClientRect();
this.lastX = (e.clientX || e.touches[0].clientX) - rect.left;
this.lastY = (e.clientY || e.touches[0].clientY) - rect.top;
},
draw(e) {
if (!this.isDrawing) return;
const canvas = this.$refs.canvas;
const ctx = canvas.getContext('2d');
const rect = canvas.getBoundingClientRect();
const currentX = (e.clientX || e.touches[0].clientX) - rect.left;
const currentY = (e.clientY || e.touches[0].clientY) - rect.top;
ctx.beginPath();
ctx.moveTo(this.lastX, this.lastY);
ctx.lineTo(currentX, currentY);
ctx.stroke();
this.lastX = currentX;
this.lastY = currentY;
},
stopDrawing() {
this.isDrawing = false;
},
clearCanvas() {
const canvas = this.$refs.canvas;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
},
async saveSignature() {
const canvas = this.$refs.canvas;
const image = await html2canvas(canvas);
const imageData = image.toDataURL('image/png');
// 可发送到服务器或下载
const link = document.createElement('a');
link.download = 'signature.png';
link.href = imageData;
link.click();
}
}
};
</script>
样式优化建议
<style scoped>
.signature-pad {
position: relative;
width: 100%;
max-width: 500px;
}
canvas {
border: 1px solid #ddd;
background-color: white;
touch-action: none; /* 防止移动端页面滚动 */
}
button {
margin-top: 10px;
padding: 8px 16px;
}
</style>
移动端适配要点
- 添加
touch-action: none防止画布上的手势触发页面滚动 - 同时监听
touchstart/touchmove/touchend事件 - 通过
e.touches[0]获取触摸点坐标 - 考虑使用
meta标签禁用缩放:<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
高级功能扩展
- 压力感应:通过
e.pressure(支持设备)实现笔迹粗细变化 - 撤销/重做:使用数组记录绘图历史
- 背景网格:在画布上绘制辅助线
- 签名验证:通过比较特征点验证签名真实性
- 服务端保存:将Base64编码的图片发送到服务器
性能优化建议
- 使用
requestAnimationFrame优化绘制性能 - 对于复杂签名,考虑使用
Path2D对象 - 防抖处理频繁的绘制事件
- 离屏Canvas缓存已绘制内容







