h5手写签名板核心是纯svg实现:监听触控/鼠标事件采集坐标,动态拼接的d属性路径字符串,辅以采样降频与贝塞尔平滑;导出时可序列化为svg矢量文件或经canvas中转生成png/jpeg图片。

在 H5 页面中实现手写签名板,核心是用 SVG 捕获触摸/鼠标轨迹并实时绘制路径,再通过 <svg></svg> 的原生矢量能力保存为 SVG 字符串,或转成 PNG/JPEG 图片。关键在于路径数据的采集、渲染与导出控制,而非依赖 Canvas。
用 SVG 实现签名绘制(纯矢量,无 Canvas)
不使用 <canvas></canvas>,而是动态创建 <path></path> 元素,将每次移动的坐标追加进 d 属性:
- 监听
touchstart/mousedown记录起始点,设置isDrawing = true - 监听
touchmove/mousemove,获取相对于 SVG 容器的坐标(需处理getScreenCTM()反向映射) - 用
moveTo(x,y) + lineTo(x,y)语法拼接d字符串,例如:"M100,200 L105,203 L112,208 ..." - 每次更新后直接设置
pathElement.setAttribute('d', dString),SVG 自动重绘
保持笔迹平滑与性能优化
原始触摸点密集且抖动,直接连点会锯齿明显。推荐轻量级平滑策略:
- 采样降频:每 15–25ms 只取一个点(用
requestAnimationFrame或节流) - 简易贝塞尔拟合:对连续 3–4 个点用二次贝塞尔曲线替代直线段(
Q cx,cy x,y),视觉更自然 - 避免高频 DOM 操作:累积 5–10 个点再批量更新一次
d,比逐点更新快 3–5 倍 - 移动端注意:禁用双指缩放(
touch-action: none),防止误触发手势
导出为 SVG 矢量文件
SVG 本质是 XML,可直接序列化当前 <svg></svg> 节点内容,保留全部缩放、线条粗细、颜色等信息:
- 用
new XMLSerializer().serializeToString(svgEl)获取完整字符串 - 添加必要命名空间声明(若缺失):
xmlns="http://www.w3.org/2000/svg" - 构造 Blob 并生成下载链接:
URL.createObjectURL(new Blob([svgStr], {type: 'image/svg+xml'})) - 用户点击即可下载标准 .svg 文件,可在 Illustrator、Inkscape 中无损编辑
导出为 PNG/JPEG 图片(含透明背景)
SVG 本身不能直接转图,需借助 <canvas></canvas> 中转,但只用于导出,不影响绘制逻辑:
- 创建临时
<canvas></canvas>,尺寸按需设定(如 800×300,保证清晰度) - 用
canvg库(轻量,支持现代浏览器)或原生ctx.drawImage(svgImage, 0, 0)渲染 SVG 到 canvas - 注意:先将 SVG 转为
data:image/svg+xml;base64,...URL,再创建Image对象加载 - 调用
canvas.toDataURL('image/png')或.toBlob()生成图片,触发下载 - 如需透明背景,确保 canvas 未填充底色,且 SVG 内部无白色矩形遮盖
整个流程不依赖第三方绘图库,纯原生 Web API 即可完成,体积小、兼容性好(iOS Safari / Android Chrome 均支持),导出结果保真度高,适合电子合同、医疗表单等对签名法律效力有要求的场景。











