vue实现电子签名、图片合成、及预览功能

业务功能:电子签名、图片合成、及预览功能

业务背景:需求说想要实现一个电子签名,然后需要提供一个预览的功能,可以查看签完名之后的完整效果。

需求探讨:后端大佬跟我说,文档我返回给你一个PDF的oss链接,然后你直接展示,你前端签完名之后给我一个base64的字符串就可以了,我回复ojbk(草率的一批)。

等我转过身,调研一下技术实现发现不对,我大前端需要做一个预览的功能啊,它需要将多张图片合成一张图片,你给我一个oss链接,我怎么转base64。带着这个想法,我跟我们的后端大佬探讨了一下,

最终确定方案是这样:

1.文档的样式由Css+Html去画

2.电子签名的模板转成base64给后端保持不变

3.前端将文档的样式和电子签名的模板合成一张图片,进行预览

根据以上,作为一名码农,我翻阅了,github,npm 找到了符合本次功能的插件。

插件:

signature_pad 签名板  链接: https://www.npmjs.com/package/signature_pad
merge-images  合并图像  链接:  https://www.npmjs.com/package/merge-images
html2canvas   html转cavas   链接:https://www.npmjs.com/package/html2canvas

先放效果图:

文档的css+html的样式,我就不献丑了哈,大家按自己的理解来。

电子签名的画板

  • html中创建一个id为signCanvas的canvas元素
<section><div class="sign-box"><p><span style="color: #f00;">*</span>{{ $t('本人签名') }}</p><el-button type="default" @click="clear(1)">{{ $t('清空') }}</el-button></div><canvas id="signCanvas" style="width:100%;height:300px;" />
</section>
  • 初始化 SignaturePad
mounted(){const canvas = document.getElementById('signCanvas')this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' })  //penColor   笔的颜色   
}

然后我就尝试了一下,发现我鼠标所在的位置跟落笔产生了偏移

然后翻阅文档发现,是需要调用一下这个 resizeCanvas 这个方法

mounted(){const canvas = document.getElementById('signCanvas')this.signatureExample = new SignaturePad(canvas, { penColor: 'rgb(0, 0, 0)' })  //penColor   笔的颜色   this.resizeCanvas()
}resizeCanvas() {const canvas = document.getElementById('signCanvas')const ratio = Math.max(window.devicePixelRatio || 1, 1) // 清除画布canvas.width = canvas.offsetWidth * ratiocanvas.height = canvas.offsetHeight * ratiocanvas.getContext('2d').scale(ratio, ratio)this.signatureExample.clear()
},

调用了一下,果然有用。

再加一个清除的方法,官方有提供,直接调用即可

this.signatureExample.clear()

canvas 转base64

this.signatureExample.toDataURL('image/png')    //得到了就是base64的   data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfgAAAL2CAYAAA......

html转cavas

  • 我们需要把html编写的文档转成base64

这个我们用html2canvas 这个插件就可以了

const element = document.querySelector('.html_body') // 需要导出的页面    哪个元素需要转成cavas  就获取它
const htmlCanvas = await html2canvas(element, {
allowTaint: true,
useCORS: true
})
this.imgSrc = htmlCanvas.toDataURL('image/png')    //得到base64

合成图片

  • 接下来我们需要将html文档和电子签名模板,合成一张图片
import mergeImages from 'merge-images'
/* x 、y 是图片在合成图片上的位置(可自行调整)  */
const mergeImagesList = [{ src: this.imgSrc, x: 0, y: 0 },   //html 转成的base64{ src: this.signatureExample.toDataURL('image/png'), x: 370, y: 440 }    //  电子签名的 base64   
]
mergeImages(mergeImagesList).then(b64 => {this.previewSrc = b64     //返回base64   可直接用于展示
})

这个时候我们看预览的结果发现,电子签名的字好大啊,这是跟我们canvas元素的大小是有关系的,如果我们改变了这个元素的大小,用户签名的时候就会体验感很差,这肯定不符合我们的预期,所以我们要把生成的电子签名等比例缩小。

通过这个方法我们可以传入我们电子签名的base64,然后生成一个新元素image ,改变它的大小,然后在通过canvas转成base64,在return 出来

PS:我们需要使用Promise去异步处理他,并拿到返回的新base64.

// 绘制的canvas 进行缩放并转为base64resizeImage(src) {return new Promise((resolve) => {const img = new Image()img.src = srcimg.onload = () => {const originalWidth = img.widthconst originalHeight = img.heightconst scaleFactor = 0.3 // 缩放的倍数const resizedWidth = originalWidth * scaleFactorconst resizedHeight = originalHeight * scaleFactorconst canvas = document.createElement('canvas')canvas.width = resizedWidthcanvas.height = resizedHeightconst ctx = canvas.getContext('2d')ctx.drawImage(img, 0, 0, resizedWidth, resizedHeight)const base64 = canvas.toDataURL('image/png')resolve(base64)}})},

然后我们重新改下合成图片的方法

  import mergeImages from 'merge-images'
const imgStr = await this.resizeImage(this.signatureExample.toDataURL('image/png'))
const mergeImagesList = [{ src: this.imgSrc, x: 0, y: 0 },   //html 转成的base64{ src: imgStr, x: 370, y: 440 }    //  电子签名的 base64   
]
mergeImages(mergeImagesList).then(b64 => {this.previewSrc = b64     //返回base64   可直接用于展示
})

ok,没问题了

还有一点需要注意的是,后端是不需要data:image/png;base64,所以还我们需要对这个字符串做个处理

// 获取到image的base64 可以把这个传到后台解析成图片
// imgStr = data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfgAAAL2CAYAAA......
// 去掉data:image/png;base64,我们只要后面的部分iVBORw0KGgoAAAANSUhEUgAAAfgAAAL2CAYAAA......
const subStr = (str) => {return str.substring(22, str.length)
}
subStr(this.signatureExample.toDataURL('image/png'))   //返回的就可以直接传给后端啦

总结

本文介绍了电子签名、图片合成、及预览功能,大体的整块逻辑及代码已提供,细节方面需要大家,自行调试哈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/388104.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【书生大模型实战营(暑假场)】入门任务一 Linux+InternStudio 关卡

入门任务一 LinuxInternStudio 关卡 参考&#xff1a; 教程任务 1 闯关任务 1.1 基于 VScode 的 SSH 链接 感谢官方教程的清晰指引&#xff0c;基于VS code 实现 SSH 的链接并不困难&#xff0c;完成公钥配之后&#xff0c;可以实现快速一键链接&#xff0c;链接后效果如下…

XXE -靶机

XXE靶机 一.扫描端口 进入xxe靶机 1.1然后进入到kali里 使用namp 扫描一下靶机开放端口等信息 1.2扫描他的目录 二 利用获取的信息 进入到 robots.txt 按他给出的信息 去访问xss 是一个登陆界面 admin.php 也是一个登陆界面 我们访问xss登陆界面 随便输 打开burpsuite抓包 发…

【MySQL】事务 【下】{重点了解读-写 4个记录隐藏列字段 undo log日志 模拟MVCC Read View sel}

文章目录 1.MVCC数据库并发的场景重点了解 读-写4个记录隐藏列字段 2.理解事务undo log日志mysql日志简介 模拟MVCC 3.Read Viewselect lock in share modeMVCC流程RR与RC 1.MVCC MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09;是…

20240801 每日AI必读资讯

&#x1f50a;OpenAI向ChatGPT Plus用户推出高级语音模式 - 只给一小部分Plus用户推送&#xff0c;全部Plus用户要等到秋季 - 被选中的Alpha 测试的用户将收到一封包含说明的电子邮件&#xff0c;并在其移动应用中收到一条消息。 - 同时视频和屏幕共享功能继续推出&#xff…

ElasticSearch父子索引实战

关于父子索引 ES底层是Lucene,由于Lucene实际上是不支持嵌套类型的,所有文档都是以扁平的结构存储在Lucene中,ES对父子文档的支持,实际上也是采取了一种投机取巧的方式实现的. 父子文档均以独立的文档存入,然后添加关联关系,且父子文档必须在同一分片,由于父子类型文档并没有…

echarts加载区域地图,并标注点

效果如下&#xff0c;加载了南海区域的地图&#xff0c;并标注几个气象站点&#xff1b; 1、下载区域地图的JSON&#xff1a;DataV.GeoAtlas地理小工具系列 新建nanhai.json&#xff0c;把下载的JSON数据放进来 说明&#xff1a;如果第二步不打勾&#xff0c;只显示省的名字&a…

ECCV 2024前沿科技速递:GLARE-基于生成潜在特征的码本检索点亮低光世界,低光环境也能拍出明亮大片!

在计算机视觉与图像处理领域&#xff0c;低光照条件下的图像增强一直是一个极具挑战性的难题。暗淡的光线不仅限制了图像的细节表现&#xff0c;还常常引入噪声和失真&#xff0c;极大地影响了图像的质量和可用性。然而&#xff0c;随着ECCV 2024&#xff08;欧洲计算机视觉会议…

应急靶场(11):【玄机】日志分析-apache日志分析

题目 提交当天访问次数最多的IP&#xff0c;即黑客IP黑客使用的浏览器指纹是什么&#xff0c;提交指纹的md5查看index.php页面被访问的次数&#xff0c;提交次数查看黑客IP访问了多少次&#xff0c;提交次数查看2023年8月03日8时这一个小时内有多少IP访问&#xff0c;提交次数 …

OrangePi AI Pro 固件升级 —— 让主频从 1.0 GHz 到 1.6 GHz 的巨大升级

前言 OrangePi AI Pro 最近发布了Ascend310B-firmware 固件包&#xff0c;据说升级之后可以将 CPU 主频从 1.0 GHz 提升至 1.6 GHz&#xff0c;据群主大大说&#xff0c;算力也从原本的 8T 提升到了 12T&#xff0c;这波开发板的成长让我非常的 Amazing 啊&#xff01;下面就来…

Linux命令行 复制模式/扩展模式 调用系统功能切换

问题背景 公司软件需要从window 适配国产操作系统&#xff0c;目前使用wine方案。在我们软件有个切换屏幕模式的功能&#xff0c;需要支持用户在我们软件内&#xff0c;切换复制模式/扩展模式。 在linux 下 uos/deepin 等系统。如果要从复制模式设置为扩展模式使用命令行时&a…

Windows下nmap命令及Zenmap工具的使用方法

一、Nmap简介 nmap是一个网络连接端扫描软件&#xff0c;用来扫描网上电脑开放的网络连接端。确定哪些服务运行在哪些连接端&#xff0c;并且推断计算机运行哪个操作系统&#xff08;这是亦称 fingerprinting&#xff09;。它是网络管理员必用的软件之一&#xff0c;以及用以评…

【Bug收割机】已解决使用maven插件打包成功,在控制台使用mvn命令打包失败问题详解,亲测有效!

文章目录 前言问题分析报错原因解决方法私域 前言 在maven项目中&#xff0c;大家经常会使用maven插件来打包项目文件 但是有的人也习惯使用mvn命令在控制台直接进行打包&#xff0c;因为这样可以自定义组装一些命令&#xff0c;使用起来也更加灵活方便&#xff0c;比如mvn pa…

C++进阶-哈希扩展(位图和布隆过滤器)

1. 位图 1.1 位图概念 面试题 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在 这40亿个数中。【腾讯】 解题思路1&#xff1a;暴⼒遍历&#xff0c;时间复杂度O(N)&#xff0c;太慢 解题思路2&#xff1a;排序⼆分查…

mybatis-plus中出现Field ‘id‘ doesn‘t have a default value问题解决方法

问题分析&#xff1a; 出现这个原因&#xff0c;主要是因为mybatis-plus自身查询的特性&#xff0c;因为查询都是它自己内部设定好的参数&#xff0c;一般为了简便&#xff0c;都会默认自己底层的数据库对应的主键id字段是自增的&#xff0c;也就是mybatis-plus认为不需要id,每…

重磅惊喜!OpenAI突然上线GPT-4o超长输出模型!「Her」高级语音模式已开放测试

在最近的大模型战争中&#xff0c;OpenAI似乎很难维持霸主地位。虽然没有具体的数据统计&#xff0c;但Claude3.5出现后&#xff0c;只是看网友们的评论&#xff0c;就能感觉到OpenAI订阅用户的流失&#xff1a; Claude3.5比GPT-4o好用&#xff0c;为什么我们不去订阅Claude呢&…

学习c语言第18天(字符串和内存函数)

1.函数介绍 1.1 strlen size_t(就是无符号整形) strlen(const char * str); 字符串已经\0作为结束标志&#xff0c;strlen函数返回的是在字符串中\0前面出现的字符个数(不包 含\0) 参数指向的字符串必须要以\0结束。 注意函数的返回值为size_t&#xff0c;…

文件系统 --- 文件结构体,文件fd以及文件描述符表

序言 在编程的世界里&#xff0c;文件操作是不可或缺的一部分。无论是数据的持久化存储、日志记录&#xff0c;还是简单的文本编辑&#xff0c;文件都扮演着至关重要的角色。然而&#xff0c;当我们通过编程语言如 C、Java 等轻松地进行文件读写时&#xff0c;背后隐藏的复杂机…

自动化运维工具之Ansible

一、Ansible Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点&#xff0c;Pubbet和Saltstack能实现的功能&#xff0c;Ansible基本上都可以实现。 Ansible能批量配置、部署、管理上千台主机…

ADS环境下的ARM汇编程序设计实验报告

ADS环境下的ARM汇编程序 一、 实验目的 1&#xff0e;了解 ARM汇编语言的基本框架,学会使用ARM的汇编语言编程。 2&#xff0e;熟悉ADS1.2下进行汇编语言程序设计的基本流程&#xff1b; 3. 了解AXD中调试功能。 二、 实验环境 硬件&#xff1a;PC机 软件&#xff1a;ADS…