vue3实现电子签名且对电子签名可进行修改画笔粗细、画笔颜色、撤销、清屏、保存等功能。
实现效果:查看源码
第一种:通过canvas
<div class="signaturePad-Box w100 h100 flex-center">
<el-space class="mb10" size="large">
<div>
<el-text>画笔粗细:</el-text>
<el-input-number v-model="state.signOptions.lineWidth" :min="2" :max="10" :step="1" @change="initCanvas" />
</div>
<div>
<el-text>画笔颜色:</el-text>
<el-color-picker v-model="state.signOptions.penColor" color-format="hex" @blur="initCanvas">
</el-color-picker></div>
</el-space>
<canvas ref="canvas" @mousedown="startDrawing" @mousemove="draw" @mouseup="stopDrawing"></canvas>
<el-space class="mt10">
<el-button @click="clear">清除</el-button>
<el-button type="success" @click="view">查看</el-button>
<el-button type="primary" @click="save">保存</el-button>
</el-space>
<el-dialog v-model="state.dialogVisible" title="查看图片" >
<el-image :src="state.dataURL" />
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="state.dialogVisible = false"> 确定 </el-button>
</div>
</template>
</el-dialog>
</div>
<script setup>
import {ref,reactive,onMounted} from "vue";
const canvas = ref(null);
const state=reactive({
dialogVisible:false,
dataURL:"",
signOptions: {
penColor: '#000000',
lineWidth: 2,
},
})
let isDrawing = false;
let lastX = 0;
let lastY = 0;
/* 初始化画布 */
const initCanvas = () => {
const ctx = canvas.value.getContext('2d');
ctx.strokeStyle = state.signOptions.penColor;
ctx.lineWidth = state.signOptions.lineWidth;
}
/* 开始绘制 */
const startDrawing = (event) => {
isDrawing = true;
[lastX, lastY] = [event.offsetX, event.offsetY];
}
/* 绘制线条 */
const draw = (event) => {
if (!isDrawing) return;
const ctx = canvas.value.getContext('2d');
const currentX = event.offsetX;
const currentY = event.offsetY;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(currentX, currentY);
ctx.stroke();
[lastX, lastY] = [currentX, currentY];
}
/* 停止绘制 */
const stopDrawing = () => {
isDrawing = false;
}
/* 清除画布 */
const clear = () => {
const ctx = canvas.value.getContext('2d');
ctx.clearRect(0, 0, canvas.value.width, canvas.value.height);
}
/* 保存签名 */
const save = () => {
state.dataURL = canvas.value.toDataURL('image/png');
console.log('签名地址为:', state.dataURL);
}
/* 查看签名 */
const view=()=>{
state.dataURL = canvas.value.toDataURL('image/png');
state.dialogVisible=true;
}
onMounted(() => initCanvas());
</script>
第二种:通过vue-signature-pad
安装依赖:
// npm
npm i vue-signature-pad
// yarn
yarn add vue-signature-pad
//pnpm
pnpm i vue-signature-pad
在main.js里引用依赖:
注:在官网上写的是全局引入非单文件引入
import VueSignaturePad from 'vue-signature-pad';
createApp(App).use(router).use(VueSignaturePad).mount('#app')
实现代码:
<template>
<div>
<el-space class="mb10" size="large">
<div>
<el-text>画笔粗细:</el-text>
<el-input-number v-model="state.size" :min="2" :max="10" :step="1" @change="onChange" />
</div>
<div>
<el-text>画笔颜色:</el-text>
<el-color-picker v-model="state.color" color-format="hex" @change="onChange"> </el-color-picker>
</div>
</el-space>
<VueSignaturePad class="line" ref="signaturePad" :options="signOptions" width="400px" height="200px" />
<el-space class="mt10">
<el-button @click="unDoSign">撤销</el-button>
<el-button @click="clearSign">清屏</el-button>
<el-button type="primary" @click="saveUploadSign">保存</el-button>
</el-space>
</div>
</template>
<script setup>
import {ref,watch} from "vue";
const signaturePad = ref();
const signOptions=ref({
penColor: '#000000',
minWidth: 1,
maxWidth:1
})
const state=ref({
color:"#000",
size:1
})
// 画笔颜色粗细改变时
const onChange=()=>{
signOptions.value={
penColor:state.value.color,
maxWidth:state.value.size
}
}
// 撤销电子签名
const unDoSign = () => {
signaturePad.value.undoSignature();
};
// 清空电子签名
const clearSign = () => {
signaturePad.value.clearSignature();
};
// 保存并上传电子签名
const saveUploadSign = async () => {
const {isEmpty,data} = signaturePad.value.saveSignature();
if (isEmpty) return;
console.log("picture url:",data);
};
</script>