前端使用Canvas实现网页电子签名(撤销、下载)
前言:一般在一些后台的流程资料以及审核的场景中会需要电子签名,介绍一种用canvas实现的电子签名,此案例用的是原生js
效果展示:

一、html和css:
<div class="divCla2"><canvas id="myCanvas" width="600" height="400"></canvas><button class="clearBtn">撤销</button><button class="downBtn">下载</button></div>
.divCla2{border: 1px solid #817e7e;width: 600px;height: 400px;
}
二、js实现逐步分析:(如果着急实现功能可以直接下滑到三)
整个电子签名的流程无非就是按下鼠标、画线、松开鼠标、停止画线
1、需要定义三个值:是否按下、当前的x坐标和y坐标,鼠标按下的时候就开始画
//获取canvas
let canvas = document.getElementById("myCanvas");
// 状态status,用于标记开始和暂停
let status = false;
//xy坐标
let x = 0;
let y = 0;
// 鼠标按下的时候开始画
canvas.addEventListener("mousedown", (e) => {status = true;x = e.offsetX;y = e.offsetY;console.log(x, y, status);
});
2、鼠标松开时就改变status的值为false
canvas.addEventListener("mouseup", () => {status = false;
});
3、鼠标移出画布时也一样:
canvas.addEventListener("mouseout", (e) => {status = false;
});
/4、鼠标移入并且status状态为true的时候就是可以画的
canvas.addEventListener("mousemove", () => {if (!status) return;
});
5、创建一个二维平面当做“笔”,并且加一些样式,比如描边颜色、拐角形状、线条末端形状、线条宽度等,然后绘制线条,可以看每一步的注释:
let ctx = canvas.getContext("2d"); // 建立二维平面
canvas.addEventListener("mousemove", (e) => {if (!status) return;//设置描边颜色ctx.strokeStyle = "#000";//拐角形状ctx.lineJoin = "round";//线条宽度ctx.lineWidth = 2;//末端形状ctx.lineCap = "round";//创建一条路径ctx.beginPath();//线条从哪里开始ctx.moveTo(x, y);//线条从哪里结束ctx.lineTo(e.offsetX, e.offsetY);//绘制路径ctx.stroke();//作为下次开始使用x = e.offsetX;y = e.offsetY;
});
这样就已经可以绘制了
6、如果写错了,需要撤销功能,使用clearRect方法:
//撤销
const clearBtn = document.querySelector(".clearBtn");
clearBtn.addEventListener("click", () => {ctx.clearRect(0, 0, canvas.width, canvas.height);
});
7、 还要配合应用场景,有些时候需要将电子签名转化成图片,然后进行下载或者传给后端等,实现下载:
//下载
let downBtn=document.querySelector(".downBtn");
downBtn.addEventListener("click",()=>{let a = document.createElement("a");a.href = canvas.toDataURL("image/png");a.download = "canvas.png";a.click();
})

三、完整代码,可以直接复制使用:
let canvas = document.getElementById("myCanvas");let status = false;
let x = 0;
let y = 0;
canvas.addEventListener("mousedown", (e) => {status = true;x = e.offsetX;y = e.offsetY;console.log(x, y, status);
});
canvas.addEventListener("mouseup", () => {status = false;
});
canvas.addEventListener("mouseout", (e) => {status = false;
});
canvas.addEventListener("mousemove", () => {if (!status) return;
});
let ctx = canvas.getContext("2d"); // 建立二维平面
canvas.addEventListener("mousemove", (e) => {if (!status) return;ctx.strokeStyle = "#000";ctx.lineJoin = "round";ctx.lineWidth = 2;ctx.lineCap = "round";ctx.beginPath();ctx.moveTo(x, y);ctx.lineTo(e.offsetX, e.offsetY);ctx.stroke();x = e.offsetX;y = e.offsetY;
});
//撤销
const clearBtn = document.querySelector(".clearBtn");
clearBtn.addEventListener("click", () => {ctx.clearRect(0, 0, canvas.width, canvas.height);
});
//下载
let downBtn=document.querySelector(".downBtn");
downBtn.addEventListener("click",()=>{let a = document.createElement("a");a.href = canvas.toDataURL("image/png");a.download = "canvas.png";a.click();
})相关文章:
前端使用Canvas实现网页电子签名(撤销、下载)
前言:一般在一些后台的流程资料以及审核的场景中会需要电子签名,介绍一种用canvas实现的电子签名,此案例用的是原生js 效果展示: 一、html和css: <div class"divCla2"><canvas id"myCanvas&q…...
Lepus安装与配置管理(Lepus Installation and Configuration Management)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...
Tomcat中存放图片文件丢失问题
1、tomcat中存放的图片丢失原因: tomcat 在处理 WAR 包时,会在部署时解压 WAR 包并创建文件夹。如果在 tomcat 运行时删除了 WAR 包,tomcat会检测到这种变化,然后可能会自动清理已解压的文件夹。这是tomcat默认的行为,…...
Webpack一键打包多个环境
1. 安装打包插件 安装如下插件,以便可以在打包命令中设置环境变量区分不同的环境。 npm install --save-dev cross-env 2. 配置打包命令 在package.json中配置正式环境和测试环境打包命令,同时添加一个命令同打包两个环境。 // package.json "…...
Neo4j 构建文本类型的知识图谱
Neo4j 是一个强大的图数据库,用于构建和查询各种类型的图数据结构。构建知识图谱是一项常见任务,尤其在处理自然语言处理 (NLP) 和文本信息时。基于 Neo4j,可以将文本数据转换为知识图谱,使得复杂的文本关系以图结构存储ÿ…...
【SSM详细教程】-03-Spring参数注入
精品专题: 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课…...
深度学习 %matplotlib inline
%matplotlib inline 是在 Jupyter Notebook 中使用的一个魔法命令,主要用于配置 Matplotlib 图形的显示方式。具体来说,这个命令的作用是将 Matplotlib 生成的图形直接嵌入到 notebook 中,而不是在弹出的窗口中显示。 使用方法 在 Jupyter …...
RT-Thread线程的定义和属性
目录 概述 1 RT-Thread线程定义 1.1 优先级设定方法 1.2 内存管理 1.2.1 RT-Thread的线程类别 1.2.2 RT-Thread的线程调度 2 线程重要属性 2.1 线程栈 2.2 线程状态 2.3 线程优先级 2.4 时间片 概述 本文主要介绍RT-Thread线程的定义和属性,其包括线程的…...
【大模型问答测试】大模型问答测试脚本实现(第二版)——接入pytest与代码解耦
背景 接上一篇,【大模型问答测试】大模型问答测试脚本实现(第一版)。 在实现自动化的时候,原先把很多方法与request请求写在一块了,趁着目前实现接口数量较少,决定对代码进行解耦,并且清晰目录…...
Windows模拟电脑假死之键盘鼠标无响应
Windows模拟电脑假死之键盘鼠标无响应 1. 场景需求 模拟Windows电脑假死,失去键盘鼠标响应。 2. 解决方案 采用Windows系统提供的钩子(Hook) API 拦截系统鼠标键盘消息。 3. 示例程序 【1】. 创建MFC对话框项目 新建一个MFC应用程序项目,项目名称…...
一文详解线程池
什么是线程池? 线程池:就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。 为什么用线程池? 线程池的优势:线程池做的工作…...
网际报文协议ICMP及ICMP重定向实例详解2
之前在一个项目中遇到了与ICMP重定向相关的问题,因为缺乏对ICMP相关内容的了解,排查了很长一段时间才查出来。本文给大家简要地介绍一下ICMP及ICMP重定向相关的内容。 1、ICMP的概念 ICMP(Internet Control Message Protocol)网际…...
CSS 总结
CSS 总结 引言 CSS(层叠样式表)是网页设计中不可或缺的一部分,它用于控制网页的布局和样式。本文将对CSS的基本概念、关键特性、常用属性以及最佳实践进行总结,旨在帮助读者深入理解并有效运用CSS。 CSS基本概念 1. 什么是CSS? CSS是一种样式表语言,用于描述HTML或X…...
C语言_指针_进阶
引言:在前面的c语言_指针初阶上,我们了解了简单的指针类型以及使用,下面我们将进入更深层次的指针学习,对指针的理解会有一个极大的提升。从此以后,指针将不再是难点,而是学习底层语言的一把利器。 本章重点…...
chat_gpt回答:python使用writearray写tiff速度太慢,有什么快速的方法吗
如果你在使用 Python 的 tifffile 库(或类似库)写入 TIFF 文件时速度太慢,以下是几个加速写入的优化方法和替代方案: 1. 优化文件压缩设置 TIFF 支持压缩格式,但压缩过程可能非常耗时。如果你不需要压缩,…...
【时时三省】(C语言基础)函数介绍strcat
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 strcat 字符串追加 示例: 比如我要把world加到hello后面去 就可以用这个 还有一种方法是这样 这两个代码的意思是一样的 只是写法不一样 写的时候要注意这些 •源字符串必须…...
ESP32C3 开发板在Linux环境下,进行JTAG 调试演示-启明云端乐鑫代理商
JTAG 调试教程 本教程主要演示 esp32c3 开发板在 linux 环境下,通过 vscode 的 esp-idf 插件使用 jtag 调试工具。 esp32c3 不但内置了USB-JTAG,还内置了USB-SERIAL,仅需要一根USB线即可实现下载和调试仿真。 下面演示调试仿真的过程。 创…...
《计算机视觉》—— 基于PyCharm中的dlib库实现人脸关键点定位
文章目录 1. 安装必要的库2. 下载dlib的人脸检测器和关键点预测器模型3. 编写代码 人脸关键点定位是指通过计算机视觉技术,识别和定位人脸图像中的关键点,如眼睛、鼻子、嘴巴等特定位置。这些关键点的准确定位对于人脸识别、表情分析、姿态估计等应用具有…...
c++习题34-说谎
目录 一,题目 二,思路 三,代码 一,题目 描述 ljc以自己的人格担保他最后一个回答一定是正确的,但并不保证其它的回答是对的。 每个数为ljc对上一个的回答,若为0表示说上句话是错的,若为…...
如何使用Android Profiler进行性能分析?
Android Profiler是Android Studio中一个功能强大的性能分析工具,它可以帮助开发者实时监控应用的CPU、内存、网络、电量和图形渲染等性能指标,从而发现并解决性能瓶颈。以下是如何使用Android Profiler进行性能分析的详细步骤和技巧。 一、准备工作 安…...
ABC系统实战指南:逻辑综合与形式验证的数字电路设计工具
ABC系统实战指南:逻辑综合与形式验证的数字电路设计工具 【免费下载链接】abc ABC: System for Sequential Logic Synthesis and Formal Verification 项目地址: https://gitcode.com/gh_mirrors/ab/abc 在现代数字电路设计流程中,逻辑综合与形式…...
联想ThinkPad声卡驱动安装避坑指南:从E470到X1 Carbon的通用解法
ThinkPad声卡驱动安装全攻略:从型号识别到疑难排解 ThinkPad作为商务笔记本的代表,其稳定性和兼容性一直备受推崇。但即便是这样成熟的产品线,声卡驱动问题依然困扰着不少用户——从经典的E470到高端的X1 Carbon,不同机型可能面临…...
x265帧内预测实战:从35种模式到MPM优化的效率提升技巧
x265帧内预测深度优化:从35种模式到MPM的工程实践 在视频编码领域,HEVC标准相比前代H.264引入了更复杂的帧内预测机制,其中x265作为开源编码器实现,其帧内预测模块的优化直接影响编码效率。本文将深入剖析x265帧内预测的核心技术…...
SWF逆向工程标准化文档:JPEXS Free Flash Decompiler实施指南
SWF逆向工程标准化文档:JPEXS Free Flash Decompiler实施指南 【免费下载链接】jpexs-decompiler JPEXS Free Flash Decompiler 项目地址: https://gitcode.com/gh_mirrors/jp/jpexs-decompiler JPEXS Free Flash Decompiler是一款强大的SWF逆向工程工具&…...
每日算法题 17---205.同构字符串
题目 205.同构字符串 要求 给定两个字符串 s 和 t ,判断它们是否是同构的。如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一…...
ArduPilot电机控制逻辑与PWM输出机制剖析
1. ArduPilot电机控制基础概念 当你第一次接触无人机飞控时,最让人困惑的莫过于电机控制逻辑了。想象一下,你手里拿着遥控器,轻轻推动摇杆,无人机就能平稳地上升、下降或者转向。这背后到底发生了什么?让我用最直白的…...
海康MVS相机+Halcon标定实战:18张图搞定畸变矫正(附标定板选购指南)
海康MVS相机Halcon标定实战:18张图搞定畸变矫正与标定板选购指南 工业视觉系统的精度往往取决于相机标定的准确性。在实际项目中,我们常遇到这样的困境:明明按照教程步骤操作,标定结果却总是不尽如人意。本文将分享一套经过实战验…...
硬件工程师职业发展路径与核心技术解析
硬件工程师的职业发展路径与技术深度探讨1. 行业现状与职业定位1.1 硬件工程师的职责演变现代硬件工程师的职责范围已从传统的电路设计扩展到系统集成、信号完整性分析、EMC设计等多个领域。典型的职责矩阵包括:职责类别传统要求现代扩展要求电路设计原理图绘制、PC…...
Claude Code 用了半年才发现,原来上下文烧没了自己根本不知道!
点击上方卡片关注我设置星标 学习更多AI出海知识用 Claude Code 最怕什么?不是它写错代码,那改改就好。最怕的是写着写着突然质量暴跌,前面说好的逻辑它不认了,该记住的上下文全忘了,然后你反应过来:上下文…...
【AI重塑科研】无需通读全文,三步教你用大模型高效产出文献综述
1. 为什么你需要AI辅助文献综述? 每次打开文献库看到上百篇待读论文就头皮发麻?我完全理解这种感受。去年准备开题报告时,导师要求我两周内完成50篇核心文献的综述,当时差点崩溃。直到我发现用大模型处理文献可以节省90%的时间&am…...
