JavaScript实现手写签名,可触屏手写,支持移动端与PC端双端保存

目录

1.HTML模板

2.获取DOM元素和定义变量

3.创建两个canvas元素,并设置它们的宽度和高度

4.绑定触摸事件:touchstart, touchmove, touchend和click

5.实现触摸事件回调函数:startDrawing, draw和stopDrawing

6.实现绘制线段的函数:drawLine

7.实现清除签名的函数:clearSignature

8.实现保存签名的函数:saveSignature

9.将canvas元素插入DOM树中

10.完整代码 

11.效果图 


1.HTML模板
<!DOCTYPE html>
<html>
<head><title></title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" /><style>/* 样式表 */</style>
</head>
<body><!-- 签名区域 --><div id="signatureArea"></div><!-- 操作按钮:清除和保存 --><button id="clearButton">清除</button><button id="saveButton">保存签名</button><!-- JavaScript代码 --><script type="text/javascript">// JavaScript代码</script>
</body>
</html>
2.获取DOM元素和定义变量
// 获取DOM元素
var signatureArea = document.getElementById('signatureArea');
var clearButton = document.getElementById('clearButton');
var saveButton = document.getElementById('saveButton');// 定义变量
var isDrawing = false; // 是否正在绘制
var lastX, lastY; // 上一个触摸点的坐标
3.创建两个canvas元素,并设置它们的宽度和高度
// 创建两个canvas元素
var drawingCanvas = document.createElement('canvas'); // 用于绘制签名
var backgroundCanvas = document.createElement('canvas'); // 用于保存带有白色背景的签名图像
var drawingCtx = drawingCanvas.getContext('2d'); // 获取绘制画布的上下文对象
var backgroundCtx = backgroundCanvas.getContext('2d'); // 获取背景画布的上下文对象
drawingCanvas.width = signatureArea.offsetWidth;
drawingCanvas.height = signatureArea.offsetHeight;
backgroundCanvas.width = drawingCanvas.width;
backgroundCanvas.height = drawingCanvas.height;
4.绑定触摸事件:touchstart, touchmove, touchend和click
// 绑定触摸事件
signatureArea.addEventListener('touchstart', startDrawing);
signatureArea.addEventListener('touchmove', draw);
signatureArea.addEventListener('touchend', stopDrawing);
clearButton.addEventListener('click', clearSignature);
saveButton.addEventListener('click', saveSignature);
5.实现触摸事件回调函数:startDrawing, draw和stopDrawing
// 开始绘制
function startDrawing(e) {e.preventDefault(); // 阻止默认事件var touch = e.touches[0]; // 获取触摸点坐标var rect = signatureArea.getBoundingClientRect(); // 获取签名区域的位置和大小lastX = touch.clientX - rect.left;lastY = touch.clientY - rect.top;isDrawing = true;
}// 绘制中
function draw(e) {if (!isDrawing) return;var touch = e.touches[0];var rect = signatureArea.getBoundingClientRect();var x = touch.clientX - rect.left;var y = touch.clientY - rect.top;drawLine(lastX, lastY, x, y);lastX = x;lastY = y;
}// 停止绘制
function stopDrawing() {isDrawing = false;
}
6.实现绘制线段的函数:drawLine
// 绘制实线
function drawLine(x1, y1, x2, y2) {drawingCtx.beginPath(); // 开始一条新的路径drawingCtx.moveTo(x1, y1); // 将画笔移动到起点drawingCtx.lineTo(x2, y2); // 绘制一条直线到终点drawingCtx.lineWidth = 1; // 设置线条的宽度为1像素drawingCtx.strokeStyle = '#000'; // 设置线条颜色为黑色drawingCtx.stroke(); // 绘制线条
}
7.实现清除签名的函数:clearSignature
// 清除签名
function clearSignature() {drawingCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height); // 清除绘制画布的内容backgroundCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height); // 清除背景画布的内容
}
8.实现保存签名的函数:saveSignature
// 保存签名
function saveSignature() {// 绘制白色背景backgroundCtx.fillStyle = 'white';backgroundCtx.fillRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);// 复制绘制的签名到带有白色背景的画布backgroundCtx.drawImage(drawingCanvas, 0, 0);// 将带有白色背景的画布内容转为PNG格式的DataURLvar dataURL = backgroundCanvas.toDataURL("image/png");// 创建一个链接元素并设置下载属性var link = document.createElement('a');link.href = dataURL;link.download = '签名.png'; // 设置下载文件的名称// 检查是否支持保存到相册if ("download" in link) {link.style.display = "none";document.body.appendChild(link);link.click();document.body.removeChild(link);} else {// 如果不支持保存到相册,你可以提供其他方式或提示用户手动保存alert("无法直接保存到相册,请手动保存签名图片。");}
}
9.将canvas元素插入DOM树中
// 将canvas元素插入DOM树中
signatureArea.appendChild(drawingCanvas);
10.完整代码 
<!DOCTYPE html>
<html>
<head><title></title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" /><style>body {font-family: Arial, sans-serif;}#signatureArea {width: 100%;height: 300px;border: 1px solid #ccc;margin-bottom: 20px;}button {padding: 10px 20px;font-size: 16px;background-color: #4CAF50;color: white;border: none;cursor: pointer;border-radius: 4px;}button:hover {background-color: #45a049;}</style>
</head>
<body><div id="signatureArea"></div><button id="clearButton">清除</button><button id="saveButton">保存签名</button><script type="text/javascript">
// 获取DOM元素
var signatureArea = document.getElementById('signatureArea');
var clearButton = document.getElementById('clearButton');
var saveButton = document.getElementById('saveButton');// 定义变量
var isDrawing = false; // 是否正在绘制
var lastX, lastY; // 上一个触摸点的坐标// 创建两个canvas元素
var drawingCanvas = document.createElement('canvas'); // 用于绘制签名
var backgroundCanvas = document.createElement('canvas'); // 用于保存带有白色背景的签名图像
var drawingCtx = drawingCanvas.getContext('2d');
var backgroundCtx = backgroundCanvas.getContext('2d');
drawingCanvas.width = signatureArea.offsetWidth;
drawingCanvas.height = signatureArea.offsetHeight;
backgroundCanvas.width = drawingCanvas.width;
backgroundCanvas.height = drawingCanvas.height;// 绑定触摸事件
signatureArea.addEventListener('touchstart', startDrawing);
signatureArea.addEventListener('touchmove', draw);
signatureArea.addEventListener('touchend', stopDrawing);
clearButton.addEventListener('click', clearSignature);
saveButton.addEventListener('click', saveSignature);// 开始绘制
function startDrawing(e) {e.preventDefault();var touch = e.touches[0];var rect = signatureArea.getBoundingClientRect();lastX = touch.clientX - rect.left;lastY = touch.clientY - rect.top;isDrawing = true;
}// 绘制中
function draw(e) {if (!isDrawing) return;var touch = e.touches[0];var rect = signatureArea.getBoundingClientRect();var x = touch.clientX - rect.left;var y = touch.clientY - rect.top;drawLine(lastX, lastY, x, y);lastX = x;lastY = y;
}// 停止绘制
function stopDrawing() {isDrawing = false;
}// 绘制实线
function drawLine(x1, y1, x2, y2) {drawingCtx.beginPath();drawingCtx.moveTo(x1, y1);drawingCtx.lineTo(x2, y2);drawingCtx.lineWidth = 1;drawingCtx.strokeStyle = '#000';drawingCtx.stroke();
}// 清除签名
function clearSignature() {drawingCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);backgroundCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);
}// 保存签名
function saveSignature() {// 绘制白色背景backgroundCtx.fillStyle = 'white';backgroundCtx.fillRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);// 复制绘制的签名到带有白色背景的画布backgroundCtx.drawImage(drawingCanvas, 0, 0);// 将带有白色背景的画布内容转为PNG格式的DataURLvar dataURL = backgroundCanvas.toDataURL("image/png");// 创建一个链接元素并设置下载属性var link = document.createElement('a');link.href = dataURL;link.download = '签名.png'; // 设置下载文件的名称// 检查是否支持保存到相册if ("download" in link) {link.style.display = "none";document.body.appendChild(link);link.click();document.body.removeChild(link);} else {// 如果不支持保存到相册,你可以提供其他方式或提示用户手动保存alert("无法直接保存到相册,请手动保存签名图片。");}
}// 将canvas元素插入DOM树中
signatureArea.appendChild(drawingCanvas);</script>
</body>
</html>
11.效果图 

 

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

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

相关文章

【PyTorch】模型选择、欠拟合和过拟合

文章目录 1. 理论介绍2. 实例解析2.1. 实例描述2.2. 代码实现2.2.1. 完整代码2.2.2. 输出结果 1. 理论介绍 将模型在训练数据上拟合的比在潜在分布中更接近的现象称为过拟合&#xff0c; 用于对抗过拟合的技术称为正则化。训练误差和验证误差都很严重&#xff0c; 但它们之间差…

Java程序员,你掌握了多线程吗?(文末送书)

目录 01、多线程对于Java的意义02、为什么Java工程师必须掌握多线程03、Java多线程使用方式04、如何学好Java多线程送书规则 摘要&#xff1a;互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀活动&#xff0c;社交平台的实时消息推送&#xff0c;还是在线视频平台的流…

@德人合科技 | 数据透明加密防泄密系统\文件文档加密\设计图纸加密|源代码加密防泄密软件系统,——防止内部办公终端核心文件数据/资料外泄!

一款专业的数据防泄密管理系统&#xff0c;它采用了多种加密模式&#xff0c;包括透明加密、半透明加密和落地加密等&#xff0c;可以有效地保护企业的核心数据安全。 PC端访问地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee …

验证码的多种生成策略

&#x1f60a; 作者&#xff1a; 瓶盖子io &#x1f496; 主页&#xff1a; 瓶盖子io-CSDN博客 第一种 a.导入依赖 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</ver…

NAS外网访问方案

基础流程 路由器开启端口映射&#xff08;如果有猫则要配置猫为转发模式&#xff0c;由路由器直接拨号即可使用第三方程序让内网ip发布到公网上&#xff08;如果有云服务器&#xff09;需要开启防火墙端口 好用的第三方程序 FRP穿透 优点&#xff1a;开源免费&#xff0c;速…

C++ 指针进阶

目录 一、字符指针 二、指针数组 三、数组指针 数组指针的定义 &数组名 与 数组名 数组指针的使用 四、数组参数 一维数组传参 二维数组传参 五、指针参数 一级指针传参 二级指针传参 六、函数指针 七、函数指针数组 八、指向函数指针数组的指针 九、回调函…

Ubuntu宝塔面板本地部署轻论坛系统HadSky并远程访问

文章目录 前言1. 网站搭建1.1 网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3 Cpolar稳定隧道&#xff08;本地设置&#xff09;2.4 公网访问测试 总结 前言 经过多年的基础…

C++多态(详解)

一、多态的概念 1.1、多态的概念 多态&#xff1a;多种形态&#xff0c;具体点就是去完成某个行为&#xff0c;当不同的对象去完成时会产生出不同的状态。 举个例子&#xff1a;比如买票这个行为&#xff0c;当普通人买票时&#xff0c;是全价买票&#xff1b;学生买票时&am…

百度推送收录工具-免费的各大搜索引擎推送工具

在互联网时代&#xff0c;网站收录是网站建设的重要一环。百度推送工具作为一种提高网站收录速度的方式备受关注。在这个信息爆炸的时代&#xff0c;对于网站管理员和站长们来说&#xff0c;了解并使用一些百度推送工具是非常重要的。本文将重点分享百度批量域名推送工具和百度…

深入理解JVM内存空间的担保策略

Java虚拟机&#xff08;JVM&#xff09;的内存管理是Java性能调优中最重要的方面之一&#xff0c;特别是在处理大型应用和服务时。JVM内存管理的一个关键组成部分是垃圾回收&#xff08;GC&#xff09;。在GC过程中&#xff0c;JVM需要确保有足够的内存来创建新对象&#xff0c…

景联文科技解读《2023人工智能基础数据服务产业发展白皮书》,助力解决数据标注挑战

前段时间&#xff0c;国家工业信息安全发展研究中心发布《2023人工智能基础数据服务产业发展白皮书》&#xff08;以下简称“白皮书”&#xff09;。 《白皮书》指出&#xff0c;2022年&#xff0c;中国人工智能基础数据服务产业的市场规模为45亿元&#xff0c;预计今年将达到5…

一步解决 java.io.FileNotFoundException: 找不到文件异常

1.问题描述 java.io.FileNotFoundException: C:\Users\Administrator\AppData\Local\Temp\localhost\uploads\image\20231206\2843cb16-9654-4e52-a757-76e3ca1f80ff.png (系统找不到指定的路径。) 2.原因分析 文件路径中的文件目录不存在 3.解决方案 方案一&#xff1a;如果…

最优化方法复习——线性规划之对偶问题

一、线性规划对偶问题定义 原问题&#xff1a; 对偶问题&#xff1a; &#xff08;1&#xff09;若一个模型为目标求 “极大”&#xff0c;约束为“小于等于” 的不等式&#xff0c;则它的对偶模型为目标求“极小”&#xff0c;约束是“大于等于”的不等式。即“Max&#xff0…

docker基本管理和概念

1、定义&#xff1a;一个开源的应用容器引擎&#xff0c;基于go语言开发&#xff0c;运行在liunx系统中的开源的、轻量级的“虚拟机” docker的容器技术可以在一台主机上轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器 docker的宿主机是liunx系统&#xff0c;集…

Maven——使用Nexus创建私服

私服不是Maven的核心概念&#xff0c;它仅仅是一种衍生出来的特殊的Maven仓库。通过建立自己的私服&#xff0c;就可以降低中央仓库负荷、节省外网带宽、加速Maven构建、自己部署构件等&#xff0c;从而高效地使用Maven。 有三种专门的Maven仓库管理软件可以用来帮助大家建立…

六个自媒体写作方法,提升自媒体创作收益

在自媒体时代&#xff0c;写作成为了一个不可或缺的技能。特别是对于新手来说&#xff0c;掌握一些有效的写作方法&#xff0c;可以事半功倍&#xff0c;更好地展现个人创意和观点。在这里&#xff0c;我将分享六个适合新手的自媒体写作方法&#xff0c;希望能够为你在写作之路…

class039 嵌套类问题的递归解题套路【算法】

class039 嵌套类问题的递归解题套路 算法讲解039【必备】嵌套类问题的递归解题套路 Code1 772. 基本计算器 III 实现一个基本的计算器来计算简单的表达式字符串。 表达式字符串只包含非负整数&#xff0c;算符、-、*、&#xff0c; ,左括号(和右括号)。整数除法需要向下截…

unity学习笔记

一、射线检测 如何让鼠标点击某个位置&#xff0c;游戏角色就能移动到该位置&#xff1f; 实现的原理分析&#xff1a;我们能看见游戏的东西就是摄像机拍摄到的东西&#xff0c;所以摄像机的镜平面就是当前能看到的了。 那接下来我们可以让摄像机发射一条射线&#xff0c;鼠标…

【网络编程】-- 01 概述、IP

网络编程 1 概述 1.1 计算机网络 (连接分散计算机设备以实现信息传递的系统) 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理和协调下&…