想要实现一个电子签名,可以支持鼠标签名,还能类似书法效果线条有粗有细,同时可以导出成图片.

一、实现连贯的划线

  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实现电子签名的更多相关文章

  1. Canvas电子签名和游戏化

    今天一天的时间都在做包团报价的无流程原型设计,一方面参考了其他系统,一方面整理先在系统中不合理的部分,规范了报价元素的分类.梳理了意向需求,其实原来粗略的放了一个模板进去是听不靠谱的.客户的要求-&g ...

  2. 做移动端电子签名发现canvas的 一些坑

    做移动端收集电子签名项目的时候发现了一些坑: 1. 移动端的手指按下.移动.抬起事件跟PC端的鼠标按下.移动.弹起事件是不一样的 2. canvas它的属性宽高和样式宽高是不一样的,通过CSS来设置c ...

  3. 表格技术七十二变|手把手教你用Canvas电子表格做电子签名

    转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 日常生活工作学习中,大家对电子表格必定不陌生.从工作数据汇总分析到出门收据各种电子发票,这些都是由电子表格制 ...

  4. 前端实现电子签名(web、移动端)通用组件(canvas实现)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. PHP《将画布(canvas)图像保存成本地图片的方法》

    用PHP将网页上的Canvas图像保存到服务器上的方法 2014年6月27日 歪脖骇客 发表回复 8 在几年前HTML5还没有流行的时候,我们的项目经理曾经向我提出这样一个需求:让项目评审专家们在评审 ...

  6. JS框架_(Esign.js)仿信用卡电子签名特效

    百度云盘 传送门 密码:l60w 电子签名特效效果: <!DOCTYPE html> <html> <head lang="en"> <m ...

  7. 迷你PS小程序-集成的开放式画报、油墨电子签名、图片拖拽可单独食用

    米娜桑,哦哈哟~ 个人制作,该文章主要讲解最近基于uni-app框架编写的集图文拖拽等多方位编辑.油墨电子签名.开放式海报于一体的小程序的制作思路和实现代码. 目录 1.完整源码链接 2.实现思路 3 ...

  8. Jquery电子签名制作_jSignature

    今天用Jquery的jSignature库制作一个电子签名 后台.net core上传到指定文件夹 下载jquery库 提取码:rd9g html @{ Layout = null; } <!D ...

  9. html5 canvas常用api总结(三)--图像变换API

    canvas的图像变换api,可以帮助我们更加方便的绘画出一些酷炫的效果,也可以用来制作动画.接下来将总结一下canvas的变换方法,文末有一个例子来更加深刻的了解和利用这几个api. 1.画布旋转a ...

  10. 【探索】利用 canvas 实现数据压缩

    前言 HTTP 支持 GZip 压缩,可节省不少传输资源.但遗憾的是,只有下载才有,上传并不支持.如果上传也能压缩,那就完美了.特别适合大量文本提交的场合,比如博客园,就是很好的例子. 虽然标准不支持 ...

随机推荐

  1. vue-test ------class绑定

    <template> <p :class="{'active':isActive}">Class样式绑定</p> <p :class=&q ...

  2. 换热站数字孪生 | 图扑智慧供热 3D 可视化

    前言 换热站作为供热系统不可或缺的一部分,其能源消耗对城市环保至关重要.在双碳目标下,供热企业可通过搭建智慧供热系统,实现供热方式的低碳.高效.智能化,从而减少碳排放和能源浪费.通过应用物联网.大数据 ...

  3. Windows 设置 VMware workstation 虚拟机开机启动

    参考 https://www.cnblogs.com/qmfsun/p/6284236.html http://www.cnblogs.com/eliteboy/p/7838091.html 司徒晓宇 ...

  4. Ubuntu部署NTP服务器和客户端

    https://www.cnblogs.com/lsgxeva/p/14265513.html Ubuntu部署NTP服务器和客户端 NTP或网络时间协议是一种协议,用于将网络中的所有系统时钟同步以使 ...

  5. 别再傻傻地用 ifconfig 查地址了!这条命令足以让你摘掉小白工程师的帽子

    大家好,我是民工哥. 众所周知,在 Linux 系统中,ip 和 ifconfig 这个两命令的功能十分相似,ifconfig 是 net-tools 中已被弃用的一个命令,很多年前就已经没有维护了. ...

  6. 【scikit-learn基础】--『监督学习』之 支持向量机分类

    支持向量机也是一种既可以处理分类问题,也可以处理回归问题的算法.关于支持向量机在回归问题上的应用,请参考:TODO 支持向量机分类广泛应用于图像识别.文本分类.生物信息学(例如基因分类).手写数字识别 ...

  7. PC端和移动端应用的开发差异

    PC端和移动端应用的开发差异主要体现在用户界面(UI)和用户体验(UX)设计.交互设计.性能优化.适配策略等方面.  

  8. 华为云张昆:支持全场景全业务,GaussDB加速企业数字化转型

    云.AI.5G等技术驱动,数据库行业迎来新的需求,云数据库也在不断演进升级.依托华为云与华为云Stack,通过全栈软硬件优化,华为云GaussDB进行了进阶与革新,以统一的架构,支持关系型与非关系型的 ...

  9. 华为云发布CodeArts Req需求管理工具,让需求管理化繁为简

    摘要:华为云正式发布CodeArts Req,这是一款自主研发的软件研发管理与团队协作工具,旨在助力企业大规模研发转型成功,释放组织生产力. 本文分享自华为云社区<华为云发布CodeArts R ...

  10. 你知道,java项目中是如何获取文件地址的吗?

    摘要:在java项目中我们经常会读取配置文件,但是文件的路径在获取时我们是怎么得到的?因为我总是忘记获取文件地址的方法,就在此记录一下 本文分享自华为云社区<[Java]Java项目的绝对地址和 ...