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>
相关推荐
邱自强33 分钟前
el-table 行列文字悬浮超出屏幕宽度不换行的问题
el-table·element-plus·el-tooltip
多客软件佳佳7 小时前
校园交友系统的设计与实现(开源版+三端交付+搭建+售后)
小程序·前端框架·uni-app·开源·php·交友
豆华8 小时前
React 中 为什么多个 JSX 标签需要被一个父元素包裹?
前端·react.js·前端框架
练习两年半的工程师8 小时前
使用React和Vite构建一个AirBnb Experiences克隆网站
前端·react.js·前端框架
林太白8 小时前
❤React-JSX语法认识和使用
前端·react.js·前端框架
女生也可以敲代码8 小时前
react中如何在一张图片上加一个灰色蒙层,并添加事件?
前端·react.js·前端框架
布兰妮甜9 小时前
前端框架大比拼:React.js, Vue.js 及 Angular 的优势与适用场景探讨
前端·vue.js·react.js·前端框架·angular.js
真的很上进10 小时前
⚡️如何在 React 和 Next.js 项目里优雅的使用 Zustand
java·前端·javascript·react.js·前端框架·vue·es6
@大迁世界10 小时前
释放 PWA 的力量:2024 年的现代Web应用|React + TypeScript 示例
前端·javascript·react.js·前端框架·ecmascript