vue3实现电子签名的方法

vue3实现电子签名且对电子签名可进行修改画笔粗细、画笔颜色、撤销、清屏、保存等功能。

实现效果:查看源码

第一种:通过canvas

javascript 复制代码
<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>
javascript 复制代码
<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

安装依赖:

javascript 复制代码
// npm
npm i vue-signature-pad

// yarn
yarn add vue-signature-pad

//pnpm 
pnpm i vue-signature-pad

在main.js里引用依赖:
注:在官网上写的是全局引入非单文件引入

javascript 复制代码
import VueSignaturePad from 'vue-signature-pad';

createApp(App).use(router).use(VueSignaturePad).mount('#app')

实现代码:

javascript 复制代码
<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>
javascript 复制代码
<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>
相关推荐
星栈独行3 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
JiaWen技术圈13 小时前
React Server Functions 深度解析
前端·react.js·前端框架
JiaWen技术圈14 小时前
React 19 并发渲染器:全面解析与实战指南
前端·react.js·前端框架
曲幽14 小时前
FastApiAdmin 后端接口开发好了,前端管理界面怎么调用与显示?
python·vue3·api·fastapi·web·ant design·view·menu·frontend
只要微微辣17 小时前
Uniapp 微信小程序 Canvas画框标注:拖拽缩放全攻略
前端·微信小程序·uni-app·canvas·canva可画
爱学习的程序媛17 小时前
微信小程序3D开发框架技术对比:XR-Frame与threejs-miniprogram
3d·微信小程序·小程序·前端框架
weixin_3975740917 小时前
ReAct推理链的工程化实现与最佳实践
前端·react.js·前端框架
放下华子我只抽RuiKe52 天前
React 从入门到生产(八):测试与部署
前端·javascript·深度学习·react.js·前端框架·ecmascript·集成学习
Maimai108082 天前
TanStack Table 入门:为什么它是 React 表格开发里的“表格引擎”
前端·javascript·react.js·架构·前端框架·reactjs
光影少年2 天前
react如何解决 Hooks 闭包陷阱
react.js·前端框架·掘金·金石计划