在Vue中实现手写签名功能,并支持笔画不连贯(即多点触控或多笔触)以及将签名部分保存为图片,可以使用<canvas>
元素配合JavaScript来实现
<template>
<div class="signature-pad">
<canvas ref="canvas" @mousedown="startDrawing" @mouseup="stopDrawing" @mousemove="draw" @mouseout="stopDrawing"
@touchstart="startDrawing" @touchend="stopDrawing" @touchmove="draw"></canvas>
<button @click="saveSignature">保存签名</button>
<img v-if="signatureImage" :src="signatureImage" alt="Signature">
</div>
</template>
<script>
export default {
name: 'SignaturePad',
data() {
return {
ctx: null,
drawing: false,
lastX: 0,
lastY: 0,
signatureImage: null
}
},
mounted() {
this.initCanvas()
},
methods: {
initCanvas() {
const canvas = this.$refs.canvas
this.ctx = canvas.getContext('2d')
this.resizeCanvas()
window.addEventListener('resize', this.resizeCanvas)
},
resizeCanvas() {
const canvas = this.$refs.canvas
canvas.width = canvas.offsetWidth
canvas.height = canvas.offsetHeight
},
startDrawing(event) {
this.drawing = true
this.lastX = event.offsetX || (event.touches ? event.touches[0].clientX : 0)
this.lastY = event.offsetY || (event.touches ? event.touches[0].clientY : 0)
},
draw(event) {
if (!this.drawing) return
const x = event.offsetX || (event.touches ? event.touches[0].clientX : 0)
const y = event.offsetY || (event.touches ? event.touches[0].clientY : 0)
this.ctx.beginPath()
this.ctx.lineWidth = 2 // 线宽可以根据需要调整
this.ctx.lineCap = 'round' // 让线条末端更圆润
this.ctx.moveTo(this.lastX, this.lastY)
this.ctx.lineTo(x, y)
this.ctx.stroke()
this.lastX = x
this.lastY = y
},
stopDrawing() {
this.drawing = false
},
saveSignature() {
const canvas = this.$refs.canvas
this.signatureImage = canvas.toDataURL('image/png')
}
}
}
</script>
<style>
.signature-pad canvas {
border: 1px dashed #ccc;
width: 100%;
height: 200px;
}
</style>