当前位置: 首页 > news >正文

js原生实现手写签名与使用signature_pad库实现手写签名

原生写法

完整代码

使用 canvas 画布绘制,input color实现颜色选择

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>手写签名</title><style>#signature-pad {border: 1px solid #000;width: 900px;height: 500px;}</style></head><body><canvas id="signature-pad"></canvas><input type="color" id="color-picker" value="#000000" /><button onclick="clearCanvas()">清除</button><button onclick="saveSignature()">保存</button></body><script>const canvas = document.getElementById('signature-pad')const ctx = canvas.getContext('2d')let painting = falseconst colorPicker = document.getElementById('color-picker')/*** 调整画布尺寸以适配高分辨率屏幕* 根据设备像素比设置画布的实际宽高,并进行缩放,防止模糊*/function resizeCanvas() {const ratio = Math.max(window.devicePixelRatio || 1, 1)canvas.width = canvas.offsetWidth * ratiocanvas.height = canvas.offsetHeight * ratiocanvas.getContext('2d').scale(ratio, ratio)}resizeCanvas()window.addEventListener('resize', resizeCanvas)/*** 开始绘制的事件处理函数* 当鼠标按下时触发,设置绘画状态为true并开始绘制* @param {MouseEvent} e - 鼠标事件对象*/function startPosition(e) {painting = truedrawLine(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop)}/*** 结束绘制的事件处理函数* 当鼠标松开或离开画布时触发,重置绘画状态和路径*/function finishPosition() {painting = falsectx.beginPath()}/*** 绘制线条函数* 在画布上绘制从上一个点到当前点的线段* @param {number} x - 当前点的x坐标(相对于画布)* @param {number} y - 当前点的y坐标(相对于画布)*/function drawLine(x, y) {if (!painting) returnctx.lineWidth = 3 // 线条宽度ctx.lineCap = 'round' // 让线条两头圆润// ctx.strokeStyle = 'red' // 设置线条颜色ctx.strokeStyle = colorPicker.value // 使用颜色选择器的值ctx.lineTo(x, y)ctx.stroke()ctx.beginPath() // 重置路径,继续绘制新的线条ctx.moveTo(x, y) // 设置下一个点的起始位置为当前点}// 绑定鼠标事件监听器canvas.addEventListener('mousedown', startPosition)canvas.addEventListener('mouseup', finishPosition)canvas.addEventListener('mousemove', function (e) {if (painting) {drawLine(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop)}})canvas.addEventListener('mouseout', finishPosition) // 当鼠标离开画布时停止绘画/*** 清除画布内容* 使用clearRect方法清空整个画布区域*/function clearCanvas() {ctx.clearRect(0, 0, canvas.width, canvas.height) // 清除画布内容}/*** 保存签名图片* 将画布内容导出为PNG格式的图片并下载到本地*/function saveSignature() {const image = canvas.toDataURL('image/png') // 将画布内容转换为DataURL格式的PNG图片数据console.log(image)const link = document.createElement('a')link.download = 'download.png'link.href = imagedocument.body.appendChild(link)link.click()document.body.removeChild(link)}</script>
</html>

使用signature_pad库

完整代码

index.html

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>手写签名</title><meta name="viewport" content="width=device-width, initial-scale=1.0" /><script src="https://cdn.jsdelivr.net/npm/signature_pad@4.1.7/dist/signature_pad.umd.min.js"></script><style>#signature-pad {border: 1px solid #000;width: 1200px;height: 500px;}</style></head><body><canvas id="signature-pad"></canvas><button onclick="clearCanvas()">清除</button><button onclick="saveSignature()">保存</button><script>const canvas = document.querySelector('canvas')const signaturePad = new SignaturePad(canvas, {minWidth: 3,maxWidth: 3,penColor: 'rgb(66, 133, 244)'})function resizeCanvas() {const ratio = Math.max(window.devicePixelRatio || 1, 1)canvas.width = canvas.offsetWidth * ratiocanvas.height = canvas.offsetHeight * ratiocanvas.getContext('2d').scale(ratio, ratio)signaturePad.clear()}resizeCanvas()window.addEventListener('resize', resizeCanvas)function clearCanvas() {signaturePad.clear()}async function saveSignature() {const png_data = await signaturePad.toDataURL()// console.log(png_data)const link = document.createElement('a')link.download = 'download.png'link.href = png_datadocument.body.appendChild(link)link.click()document.body.removeChild(link)// console.log(signaturePad.toDataURL('image/jpeg'))}</script></body>
</html>

代码解释

1、初始化

1、获取canvas画布dom;

2、初始化 SignaturePad 库;

3、设置初始属性;

const canvas = document.querySelector('canvas')
const signaturePad = new SignaturePad(canvas, {minWidth: 3,maxWidth: 3,penColor: 'rgb(66, 133, 244)'
})

2、处理高DPI屏幕

如果不动态设置画布比例,会出现画笔错位问题

function resizeCanvas() {const ratio = Math.max(window.devicePixelRatio || 1, 1)canvas.width = canvas.offsetWidth * ratiocanvas.height = canvas.offsetHeight * ratiocanvas.getContext('2d').scale(ratio, ratio)signaturePad.clear()
}
resizeCanvas()
window.addEventListener('resize', resizeCanvas)

3、清除按钮

调用库自带方法清除已写内容

function clearCanvas() {signaturePad.clear()
}

4、保存按钮

生成png图片并下载

async function saveSignature() {const png_data = await signaturePad.toDataURL()// console.log(png_data)const link = document.createElement('a')link.download = 'download.png'link.href = png_datadocument.body.appendChild(link)link.click()document.body.removeChild(link)
}

官方参考

signature_pad - npm

http://www.xdnf.cn/news/1309321.html

相关文章:

  • 【科研绘图系列】R语言在DOM再矿化数据分析与可视化中的应用
  • 【CF】Day128——杂题 (图论 + 贪心 | 集合 + 贪心 + 图论 | 二分答案 + 贪心)
  • bev 感知算法 近一年来的新进展
  • echarts 画一个饼图,并且外围有一个旋转动画
  • pytest tmpdir fixture介绍(tmpdir_factory)(自动在测试开始前创建一个临时目录,并在测试结束后删除该目录)
  • 【LeetCode题解】LeetCode 35. 搜索插入位置
  • flowable汇总查询方式
  • ktg-mes 改造成 Saas 系统
  • Golang分布式事务处理方案
  • ROS move_base 混合功能导航 RealSense D435i + 3D 点云地图 + 楼层切换 + 路径录制 + 路径规划
  • 适合2D而非3D的游戏
  • Rust学习笔记(四)|结构体与枚举(面向对象、模式匹配)
  • 从舒适度提升到能耗降低再到安全保障,楼宇自控作用关键
  • 奈飞工厂 —— 算法优化实战推荐
  • JavaScript手录17-原型
  • 2025年生成式引擎优化(GEO)服务商技术能力评估报告
  • 【Docker】Ubuntu上安装Docker(网络版)
  • [创业之路-550]:公司半年度经营分析会 - 常见差距与根因分析示例
  • linux网络基础
  • 022 基础 IO —— 文件
  • Redis-plus-plus 安装指南
  • 161. Java Lambda 表达式 - 使用工厂方法创建 Predicates
  • 力扣(LeetCode) ——142. 环形链表 II(C语言)
  • OpenShift 4.19安装中的变化
  • Vue 3与React内置组件全对比
  • Hadoop面试题及详细答案 110题 (16-35)-- HDFS核心原理与操作
  • 音视频学习(五十四):基于ffmpeg实现音频重采样
  • 基于单片机的防酒驾系统设计
  • 我的世界Java版1.21.4的Fabric模组开发教程(十八)自定义传送门
  • 《C++进阶之继承多态》【多态:概念 + 实现 + 拓展 + 原理】