vue实现签字
安装依赖。
·
方案一、使用vue-esign插件
安装依赖
npm install vue-esign --save
在main.js中引入:
import vueEsign from 'vue-esign'
Vue.use(vueEsign)
在组件中使用:
<template>
<div>
<vue-esign ref="esign" :width="500" :height="300" :isCrop="isCrop" :lineWidth="lineWidth" :lineColor="lineColor"
:bgColor.sync="bgColor" />
<button @click="handleReset">清空画板</button>
<button @click="handleGenerate">生成图片</button>
<div>
<img :src="resultImg">
</div>
</div>
</template>
<script>
export default {
data() {
return {
lineWidth: 6,
lineColor: '#000000',
bgColor: '',
isCrop: false,
resultImg: ''
}
},
methods: {
handleReset() {
this.$refs.esign.reset()
},
handleGenerate() {
this.$refs.esign.generate().then(res => {
this.resultImg = res
// 将base64转换为文件
const blob = this.dataURLtoBlob(res)
const file = this.blobToFile(blob, 'signature.jpg')
// 可以上传到服务器
}).catch(() => {
alert('请先签名')
})
},
dataURLtoBlob(dataurl) {
const arr = dataurl.split(',')
const mime = arr[0].match(/:(.*?);/)[1]
const bstr = atob(arr[1])
let n = bstr.length
const u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
},
blobToFile(theBlob, fileName) {
theBlob.lastModifiedDate = new Date()
theBlob.name = fileName
return theBlob
}
}
}
</script>
方案二、使用vue-signature-pad插件
下载依赖
npm install vue-signature-pad@2.0.5 --save
在main.js中引入
import Vue from 'vue'
import VueSignaturePad from 'vue-signature-pad'
Vue.use(VueSignaturePad)
在组件中使用:
<template>
<div>
<vue-signature-pad
id="signature"
width="95%"
height="400px"
ref="signaturePad"
:options="options"
/>
<button @click="save">保存</button>
<button @click="clear">清除</button>
</div>
</template>
<script>
export default {
data() {
return {
options: {
penColor: '#000',
},
}
},
methods: {
save() {
const { isEmpty, data } = this.$refs.signaturePad.saveSignature()
if (isEmpty) {
alert('请先签名');
return;
}
console.log(data); // 这里是base64格式的签名图片
// 可以发送到后端或保存到本地
},
clear() {
this.$refs.signaturePad.clearSignature()
},
}
}
</script>
方案三、使用插件 signature_pad,支持撤销、重做等高级功能
安装依赖
npm install signature_pad
在Vue组件中使用:
<template>
<div class="sign-box">
<canvas ref="signCanvas"></canvas>
<button @click="clear">清除</button>
<button @click="save">保存</button>
</div>
</template>
<script>
import SignaturePad from 'signature_pad';
export default {
data() {
return {
signaturePad: null
};
},
mounted() {
const canvas = this.$refs.signCanvas;
this.signaturePad = new SignaturePad(canvas, {
penColor: 'rgb(0, 0, 0)'
});
// 校正签名位置偏移
this.adjustSignatureImgPos();
},
methods: {
adjustSignatureImgPos() {
const canvas = this.$refs.signCanvas;
const ratio = Math.max(window.devicePixelRatio || 1, 1);
canvas.width = canvas.offsetWidth * ratio;
canvas.height = canvas.offsetHeight * ratio;
// canvas.getContext('2d').scale(ratio, ratio);
},
clear() {
this.signaturePad.clear();
},
save() {
const signatureImgSrc = this.signaturePad.toDataURL('image/png');
console.log(signatureImgSrc); // base64格式的签名图片
// 可以发送到后端或保存到本地
}
}
};
</script>
方案四、使用原生Canvas实现,但需要自行处理绘制逻辑和跨设备适配
使用原生实现
<template>
<div class="signature-pad">
<canvas
ref="signatureCanvas"
@touchstart="startDrawingTouch"
@touchmove="drawTouch"
@touchend="stopDrawingTouch"
@mousedown="startDrawing"
@mousemove="draw"
@mouseup="stopDrawing"
></canvas>
<div class="controls">
<button @click="clearCanvas">清除</button>
<button @click="saveSignature">保存</button>
</div>
<img v-if="signatureImage" :src="signatureImage" alt="签名预览">
</div>
</template>
<script>
export default {
data() {
return {
isDrawing: false,
lastX: 0,
lastY: 0,
signatureImage: null
};
},
mounted() {
this.initCanvas();
},
methods: {
initCanvas() {
const canvas = this.$refs.signatureCanvas;
const ctx = canvas.getContext('2d');
// 设置画布大小
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
// 设置绘制样式
ctx.strokeStyle = '#000000';
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
},
// PC端绘制
startDrawing(e) {
this.isDrawing = true;
const canvas = this.$refs.signatureCanvas;
[this.lastX, this.lastY] = [e.offsetX, e.offsetY];
},
draw(e) {
if (!this.isDrawing) return;
const canvas = this.$refs.signatureCanvas;
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(this.lastX, this.lastY);
ctx.lineTo(e.offsetX, e.offsetY);
ctx.stroke();
[this.lastX, this.lastY] = [e.offsetX, e.offsetY];
},
stopDrawing() {
this.isDrawing = false;
},
// 移动端绘制
startDrawingTouch(e) {
this.isDrawing = true;
const canvas = this.$refs.signatureCanvas;
const touch = e.touches[0];
const rect = canvas.getBoundingClientRect();
[this.lastX, this.lastY] = [
touch.clientX - rect.left,
touch.clientY - rect.top
];
},
drawTouch(e) {
if (!this.isDrawing) return;
const canvas = this.$refs.signatureCanvas;
const ctx = canvas.getContext('2d');
const touch = e.touches[0];
const rect = canvas.getBoundingClientRect();
const x = touch.clientX - rect.left;
const y = touch.clientY - rect.top;
ctx.beginPath();
ctx.moveTo(this.lastX, this.lastY);
ctx.lineTo(x, y);
ctx.stroke();
[this.lastX, this.lastY] = [x, y];
e.preventDefault(); // 防止页面滚动
},
stopDrawingTouch() {
this.isDrawing = false;
},
// 清除画布
clearCanvas() {
const canvas = this.$refs.signatureCanvas;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
this.signatureImage = null;
},
// 保存签名
saveSignature() {
const canvas = this.$refs.signatureCanvas;
this.signatureImage = canvas.toDataURL('image/png'); // 获取签名图像的Base64字符串
// 可以在这里将base64发送到后端或保存到本地
}
}
};
</script>
<style scoped>
.signature-pad {
display: flex;
flex-direction: column;
align-items: center;
}
.signature-canvas {
border: 1px solid #ccc;
cursor: crosshair;
width: 100%;
height: 300px;
}
.controls {
margin-top: 10px;
}
button {
margin: 0 5px;
padding: 8px 16px;
background: #409eff;
color: white;
border: none;
border-radius: 4px;
}
img {
margin-top: 10px;
max-width: 100%;
max-height: 300px;
}
</style>
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)