Vue实现电子签名功能的完整代码
作者:hhzz
本文介绍了在Vue项目中实现电子签名功能的步骤,包括将原始文档转换为图片、使用`signature_pad`和`html2canvas`库、调整签名位置和缩放比例、合并图片等步骤,并提供了完整的源码,需要的朋友可以参考下
一、具体思路
在vue项目中使用以下步骤思路去实现:
起初的原始文档的格式都转成图片格式来处理;
电子签名的模板转成base64
前端将文档的样式和电子签名的模板合成一张图片,进行预览
通过原始图片文档与电子签名的图片进行合并,期间需要调整签名base64的位置和缩放比例,然后添加合并到原始文档,最终形成签名后的文档。
二、所需依赖
npm i signature_pad@4.2.0 npm i html2canvas
signature_pad 签名板
signature_pad - npm
html2canvas html转cavas
html2canvas - npm
三、添加签名面板
<div class="sign-box" style="width:300px;height:200px;padding: 10px; margin:10px;background-color: rgb(221 216 216);"> <p><span style="color: #f00;">*</span>签名版<span style="color: #f00;">*</span></p> <div> <canvas id="signCanvas"/> </div> <button type="default" @click="clear()">清除</button> <button type="default" @click="review()">游览</button> <button aria-placeholder="添加签名到文件" type="default" @click="submit()">提交</button> </div>
import SignaturePad from 'signature_pad'
mounted() { const canvas = document.getElementById('signCanvas') this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' }) //penColor 笔的颜色 },
发现我鼠标所在的位置跟落笔产生了偏移 需要调用一下这个 adjustSignatureImgPos这个方法
//校正签名位置偏移 adjustSignatureImgPos() { const canvas = document.getElementById('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) },
mounted() { const canvas = document.getElementById('signCanvas') this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' }) //penColor 笔的颜色 this.adjustSignatureImgPos() },
3.1 canvas 转base64
this.signatureimgSrc =this.signatureExample.toDataURL('image/png') //得到了就是base64的
打印输入如下:
3.2 电子签名等比例缩小
把生成的电子签名等比例缩小
传入我们电子签名的base64,然后生成一个新元素image ,改变它的大小,然后在通过canvas转成base64,在return 出来
我们需要使用Promise去异步处理他,并拿到返回的新base64
// 绘制的canvas 进行缩放并转为base64 resizeImage(src) { return new Promise((resolve) => { const img = new Image() img.src = src img.onload = () => { const originalWidth = img.width const originalHeight = img.height const scaleFactor = 0.5 // 缩放的倍数 const resizedWidth = originalWidth * scaleFactor const resizedHeight = originalHeight * scaleFactor const canvas = document.createElement('canvas') canvas.width = resizedWidth canvas.height = resizedHeight const ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0, resizedWidth, resizedHeight) const base64 = canvas.toDataURL('image/png') resolve(base64) } }) },
效果如下:
四、html转cavas(原始文档)
我们需要把html编写的文档转成base64
这个我们用html2canvas 这个插件:
import html2canvas from 'html2canvas'
html2canvas(document.querySelector("#capture")).then(canvas => { this.htmlimgUrl = canvas.toDataURL("image/png"); // 将canvas转换成img的src流 });
五、合成图片
接下来我们需要将html文档和电子签名模板,合成一张图片
写一个合并图片的方法:
传入两个参数,分别是原始图片文档和电子签名图片文档;
//合并图片 mergeimg(imgUrl,signatureimgSrc){ // 创建一个 canvas 元素 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 创建两个图像对象 const img1 = new Image(); const img2 = new Image(); // 设置图像的 src 属性为 Base64 编码的字符串 img1.src = imgUrl; img2.src = signatureimgSrc; // 设置 canvas 的宽度和高度 // 这里假设我们将图像水平排列,因此宽度是两幅图宽度之和,高度取最大值 canvas.width = img1.width + img2.width; canvas.height = Math.max(img1.height, img2.height); // 绘制第一张图像 ctx.drawImage(img1, 0, 0); // 绘制第二张图像,放置在第一张图像的右边 ctx.drawImage(img2, 300, 500); // 将合并后的图像导出为 Base64 编码的字符串 this.mergedImage = canvas.toDataURL('image/png'); },
调用合并图片方法:
//点击提交 进行合并图片 保存签名面板内容 submit(){ this.mergeimg(this.imgUrl,this.signatureimgSrcScale) },
六、效果测试
七、完整源码
<template> <div class="page"> <div> <h3>原文档</h3> <h3>-----------------------</h3> <img :src="imgUrl"> </div> <div class="sign-box" style="width:300px;height:200px;padding: 10px; margin:10px;background-color: rgb(221 216 216);"> <p><span style="color: #f00;">*</span>签名版<span style="color: #f00;">*</span></p> <div> <canvas id="signCanvas"/> </div> <button type="default" @click="clear()">清除</button> <button type="default" @click="review()">游览</button> <button aria-placeholder="添加签名到文件" type="default" @click="submit()">提交</button> </div> <div> <h3>签名</h3> <img :src="signatureimgSrcScale"> </div> <div> <h3>签名后的文档</h3> <h3>-----------------------</h3> <img :src="mergedImage"> </div> </div> </template> <script> import SignaturePad from 'signature_pad' import html2canvas from 'html2canvas' import pdf from 'vue-pdf' export default { components: { pdf }, data() { return { imgUrl: '../../static/file.png', signatureimgSrc: null, htmlimgUrl: null, signatureExample: null, mergedImage: null, signatureimgSrcScale: null } }, mounted() { const canvas = document.getElementById('signCanvas') this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' }) //penColor 笔的颜色 this.adjustSignatureImgPos() }, created() { }, methods: { //校正签名位置偏移 adjustSignatureImgPos() { const canvas = document.getElementById('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) }, //html页面内容转为base64 html2base64(){ html2canvas(document.querySelector("#capture")).then(canvas => { this.htmlimgUrl = canvas.toDataURL("image/png"); // 将canvas转换成img的src流 }); }, //合并图片 mergeimg(imgUrl,signatureimgSrc){ // 创建一个 canvas 元素 const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); // 创建两个图像对象 const img1 = new Image(); const img2 = new Image(); // 设置图像的 src 属性为 Base64 编码的字符串 img1.src = imgUrl; img2.src = signatureimgSrc; // 等待两张图像都加载完毕 // await Promise.all([this.loadImage(img1), this.loadImage(img2)]); // 设置 canvas 的宽度和高度 // 这里假设我们将图像水平排列,因此宽度是两幅图宽度之和,高度取最大值 canvas.width = img1.width + img2.width; canvas.height = Math.max(img1.height, img2.height); // 绘制第一张图像 ctx.drawImage(img1, 0, 0); // 绘制第二张图像,放置在第一张图像的右边 ctx.drawImage(img2, 300, 500); // 将合并后的图像导出为 Base64 编码的字符串 this.mergedImage = canvas.toDataURL('image/png'); }, loadImage(img) { return new Promise((resolve, reject) => { img.onload = resolve; img.onerror = reject; }); }, //点击清除按钮 清除签名面板内容 clear(){ //清除签名面板的方法 this.signatureExample.clear() }, async review(){ this.signatureimgSrc =this.signatureExample.toDataURL('image/png') this.signatureimgSrcScale =await this.resizeImage(this.signatureExample.toDataURL('image/png')) console.log("======== this.signatureimgSrc==========", this.signatureimgSrc) }, //点击提交 进行合并图片 保存签名面板内容 submit(){ this.mergeimg(this.imgUrl,this.signatureimgSrcScale) }, // 绘制的canvas 进行缩放并转为base64 resizeImage(src) { return new Promise((resolve) => { const img = new Image() img.src = src img.onload = () => { const originalWidth = img.width const originalHeight = img.height const scaleFactor = 0.5 // 缩放的倍数 const resizedWidth = originalWidth * scaleFactor const resizedHeight = originalHeight * scaleFactor const canvas = document.createElement('canvas') canvas.width = resizedWidth canvas.height = resizedHeight const ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0, resizedWidth, resizedHeight) const base64 = canvas.toDataURL('image/png') resolve(base64) } }) }, } } </script> <style> .page{ display: flex; flex-direction: row; margin: 10px; text-align: center; background: #fff; padding: 10px; } </style>
到此这篇关于Vue实现电子签名功能的完整代码的文章就介绍到这了,更多相关Vue电子签名内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!