如何通过canvas实现电子签名
想要实现一个电子签名,可以支持鼠标签名,还能类似书法效果线条有粗有细,同时可以导出成图片.
一、实现连贯的划线
1)首先需要注册鼠标下压、鼠标放开、鼠标移出和鼠标移动事件,通过鼠标下压赋值downFlag标记开始绘制
2) 鼠标移动时,将当前坐标位置传入绘制方法,通过lineTo方法实现绘制
/**
* 按下鼠标启动绘制标记
**/
canvas.addEventListener('mousedown', e => {
preCoord = [e.offsetX, e.offsetY, new Date().getTime()];
downFlag = true;
}) /**
* 鼠标松开结束绘制
**/
canvas.addEventListener('mouseup', e => {
downFlag = false;
})
canvas.addEventListener('mouseout', () => {
downFlag = false;
}) /**
* 鼠标移动时绘制文字
**/
canvas.addEventListener('mousemove', e => {
if (downFlag) {
const coord = [e.offsetX, e.offsetY];
drawSign(coord);
preCoord = [...coord, new Date().getTime()];
}
})
3) 启动线的绘制,其中注释的线段
function drawSign(coord) {
// 为了实现阶段性线的不同粗细程度,所以每次绘制必须重新开始一段路径
ctx.beginPath();
getColor(coord);
ctx.lineTo(...preCoord);
ctx.lineTo(...coord);
ctx.stroke();
ctx.closePath();
}
二、为了美观,实现书法类似的效果,需要设每个线段设置不同的宽度才可以
1)根据每两个事件点的时间差计算一个倍数关系,然后乘以一个基础宽度就可以得到不同的宽度,本文实现的效果是绘制越慢线条越宽,越快线条越窄

2) 设置线的连接方式和线端点效果,使整个线条看起来更加圆滑
/**
* 根据绘制时间差设置绘制线宽
**/
function getColor(coord) {
if (preCoord.length === 0) {
return;
}
// 当前是计算的每两个点的时间差是五毫秒的倍数
const tempMulti = (new Date().getTime() - preCoord[2]) / 5;
if (tempMulti > multi) {
multi = multi * 1.4;
} else {
multi = multi * 0.9;
}
if (multi > 5) {
multi = 5;
}
if (multi < 1) {
multi = 1;
}
ctx.lineWidth = 2 * multi; // 通过设置连线效果和线端点效果可以使线条看起来更圆滑
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.strokeStyle = 'rgba(153, 153, 153, 1)';
}
三、下面奉上完整的代码和效果图

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>signature</title>
</head>
<body style="text-align: center;">
<div>
<button id="output" style="margin: 10px;">导出</button>
</div> <canvas id="canvas" width="800" height="800" style="width: 800px;height: 800px;border: 1px solid gray;"></canvas>
</body>
</html>
<script type="module">
window.onload = (() => {
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d'); // 上一个绘制点的坐标
let preCoord = [];
// 绘制启动标志
let downFlag = false;
// 初始线宽
let multi = 5; /**
* 按下鼠标启动绘制标记
**/
canvas.addEventListener('mousedown', e => {
preCoord = [e.offsetX, e.offsetY, new Date().getTime()];
downFlag = true;
}) /**
* 鼠标松开结束绘制
**/
canvas.addEventListener('mouseup', e => {
downFlag = false;
})
canvas.addEventListener('mouseout', () => {
downFlag = false;
}) /**
* 鼠标移动时绘制文字
**/
canvas.addEventListener('mousemove', e => {
if (downFlag) {
const coord = [e.offsetX, e.offsetY];
drawSign(coord);
preCoord = [...coord, new Date().getTime()];
}
}) document.getElementById('output').addEventListener('click', e => {
const a = document.createElement('a');
a.href = canvas.toDataURL('image/png');
a.download = 'signature.png';
a.click();
}) /**
* 根据绘制时间差设置绘制线宽
**/
function getColor(coord) {
if (preCoord.length === 0) {
return;
}
// 当前是计算的每两个点的时间差是五毫秒的倍数
const tempMulti = (new Date().getTime() - preCoord[2]) / 5;
if (tempMulti > multi) {
multi = multi * 1.4;
} else {
multi = multi * 0.9;
}
if (multi > 5) {
multi = 5;
}
if (multi < 1) {
multi = 1;
}
ctx.lineWidth = 2 * multi; // 通过设置连线效果和线端点效果可以使线条看起来更圆滑
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.strokeStyle = 'rgba(153, 153, 153, 1)';
} function drawSign(coord) {
// 为了实现阶段性线的不同粗细程度,所以每次绘制必须重新开始一段路径
ctx.beginPath();
getColor(coord); ctx.lineTo(...preCoord);
ctx.lineTo(...coord); ctx.stroke();
ctx.closePath();
}
})
</script>
完整代码

如何通过canvas实现电子签名的更多相关文章
- Canvas电子签名和游戏化
今天一天的时间都在做包团报价的无流程原型设计,一方面参考了其他系统,一方面整理先在系统中不合理的部分,规范了报价元素的分类.梳理了意向需求,其实原来粗略的放了一个模板进去是听不靠谱的.客户的要求-&g ...
- 做移动端电子签名发现canvas的 一些坑
做移动端收集电子签名项目的时候发现了一些坑: 1. 移动端的手指按下.移动.抬起事件跟PC端的鼠标按下.移动.弹起事件是不一样的 2. canvas它的属性宽高和样式宽高是不一样的,通过CSS来设置c ...
- 表格技术七十二变|手把手教你用Canvas电子表格做电子签名
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 日常生活工作学习中,大家对电子表格必定不陌生.从工作数据汇总分析到出门收据各种电子发票,这些都是由电子表格制 ...
- 前端实现电子签名(web、移动端)通用组件(canvas实现)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- PHP《将画布(canvas)图像保存成本地图片的方法》
用PHP将网页上的Canvas图像保存到服务器上的方法 2014年6月27日 歪脖骇客 发表回复 8 在几年前HTML5还没有流行的时候,我们的项目经理曾经向我提出这样一个需求:让项目评审专家们在评审 ...
- JS框架_(Esign.js)仿信用卡电子签名特效
百度云盘 传送门 密码:l60w 电子签名特效效果: <!DOCTYPE html> <html> <head lang="en"> <m ...
- 迷你PS小程序-集成的开放式画报、油墨电子签名、图片拖拽可单独食用
米娜桑,哦哈哟~ 个人制作,该文章主要讲解最近基于uni-app框架编写的集图文拖拽等多方位编辑.油墨电子签名.开放式海报于一体的小程序的制作思路和实现代码. 目录 1.完整源码链接 2.实现思路 3 ...
- Jquery电子签名制作_jSignature
今天用Jquery的jSignature库制作一个电子签名 后台.net core上传到指定文件夹 下载jquery库 提取码:rd9g html @{ Layout = null; } <!D ...
- html5 canvas常用api总结(三)--图像变换API
canvas的图像变换api,可以帮助我们更加方便的绘画出一些酷炫的效果,也可以用来制作动画.接下来将总结一下canvas的变换方法,文末有一个例子来更加深刻的了解和利用这几个api. 1.画布旋转a ...
- 【探索】利用 canvas 实现数据压缩
前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...
随机推荐
- Reactor实战,创建一个简单的单线程Reactor(理解了就相当于理解了多线程的Reactor)
单线程Reactor package org.example.utils.echo.single; import java.io.IOException; import java.net.InetSo ...
- PTA 函数与递归部分题目讲解及思路
7-1 判断素数 题目分析 题目输入n个数,判断其是否为质数 对于判断质数,只需要满足从2开始遍历的每一个数一直到√n均无法被n整除即可 关于为什么只要到√n呢? 因为n = √n * √n,因此其最 ...
- 在 IIS 上生成经典 ASP 网站
场景:在 IIS 上生成经典 ASP 网站 本文档将指导你完成安装 IIS 和配置经典 ASP 网站的过程. 经典 ASP 是服务器端脚本环境,可用于创建和运行动态 Web 应用程序. 借助 ASP, ...
- IPv6规模部署和应用成必然趋势,IPv6监测具有很大市场潜力
日前,中央网信办.国家发展改革委.工业和信息化部联合印发<深入推进IPv6规模部署和应用2021年工作安排>.这更深入的表明,IPv6规模部署和应用是互联网演进升级的必然趋势,是网络技术创 ...
- 文心一言 VS 讯飞星火 VS chatgpt (177)-- 算法导论13.3 6题
六.用go语言,说明如果红黑树的表示中不提供父指针,应当如何有效地实现 RB-INSERT. 文心一言: 红黑树是一种自平衡的二叉搜索树,其中每个节点都包含一个颜色属性(红色或黑色),并且满足以下性质 ...
- 2023-09-10:用go语言编写。作为项目经理,你规划了一份需求的技能清单 req_skills, 并打算从备选人员名单 people 中选出些人组成一个「必要团队」 ( 编号为 i 的备选人员
2023-09-10:用go语言编写.作为项目经理,你规划了一份需求的技能清单 req_skills, 并打算从备选人员名单 people 中选出些人组成一个「必要团队」 ( 编号为 i 的备选人员 ...
- 聚焦企业开放OpenAPI痛难点,华为云API Explorer助力构建API门户
本文分享自华为云社区<聚焦企业开放OpenAPI痛难点,华为云API Explorer助力伙伴构建API门户>,作者:华为云PaaS服务小智. 当前,IT研发的主流架构已从单体架构向微服务 ...
- 微服务下,使用 ELK 进行日志采集以及统一处理
摘要:微服务各个组件的相关实践会涉及到工具,本文将会介绍微服务日常开发的一些利器,这些工具帮助我们构建更加健壮的微服务系统,并帮助排查解决微服务系统中的问题与性能瓶颈等. 微服务各个组件的相关实践会涉 ...
- 科技抗疫,少年可期,为这群有AI的天使开发者疯狂打call
摘要:2020年初新冠突发,在这场抗疫的战斗中,让我们深刻体会到,疫情与每一个人息息相关.有这样一群来自华中科技大学的师生项目团队,他们利用AI技术,助力全球抗疫,他们是怎么做的呢?让我们一起来看看吧 ...
- 5分钟体验代码仓托管、CloudIDE云端代码编辑、调试、运行
摘要:您将学会如何通过代码托管(CodeHub)创建代码仓,解决软件开发者在跨地域协同.多分支并发.代码版本管理.安全性等方面的问题. 本文分享自华为云社区<5分钟体验代码仓托管.CloudID ...