Canvas 手写签名/涂鸦:触屏变形问题终极解决
背景
项目需要实现手写签名 + 指纹叠加功能。最初用 Java 后端合成图片,流程繁琐;改用前端 Canvas 直接绘制,简单高效。
但遇到一个严重问题:触屏快速签名/涂鸦时,线条严重变形,圆变成多边形、笔画卡顿断裂。
原因
触屏浏览器默认会触发页面滚动、缩放、双击放大等行为,这些默认事件会干扰 Canvas 绘制,导致坐标不准、线条抖动变形。
核心解决:
在 touchstart/touchmove 事件里加上 e.preventDefault(),阻止浏览器默认行为。
完整实现代码
1. HTML(画布)
<canvas id="signatureCanvas" width="600" height="300" style="border:1px solid #ccc;"></canvas>
<button onclick="clearCanvas()">清空</button>
2. JavaScript(绘制逻辑 + 防变形关键)
const canvas = document.getElementById('signatureCanvas');
const ctx = canvas.getContext('2d');
// 画笔样式
ctx.lineWidth = 6;
ctx.lineCap = 'round'; // 圆角端点
ctx.lineJoin = 'round'; // 圆角连接
let drawing = false;
let vertex = canvas.getBoundingClientRect(); // 画布位置
// 开始绘制:鼠标按下 / 触屏按下
canvas.addEventListener('mousedown', startDraw);
canvas.addEventListener('touchstart', startDraw);
// 绘制中:鼠标移动 / 触屏移动
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('touchmove', draw);
// 结束绘制:鼠标抬起 / 触屏离开
canvas.addEventListener('mouseup', stopDraw);
canvas.addEventListener('mouseleave', stopDraw);
canvas.addEventListener('touchend', stopDraw);
// 开始绘制
function startDraw(e) {
e.preventDefault(); // 关键:阻止默认行为,解决触屏变形
drawing = true;
ctx.beginPath();
// 获取坐标(兼容鼠标 + 触屏)
const { x, y } = getPos(e);
ctx.moveTo(x, y);
}
// 绘制过程
function draw(e) {
if (!drawing) return;
e.preventDefault(); // 关键:移动时也要阻止默认行为
const { x, y } = getPos(e);
ctx.lineTo(x, y);
ctx.stroke();
}
// 结束绘制
function stopDraw() {
drawing = false;
ctx.closePath();
}
// 坐标转换:适配鼠标/触屏
function getPos(e) {
if (e.type.includes('touch')) {
const touch = e.touches[0] || e.changedTouches[0];
return {
x: touch.clientX - vertex.left,
y: touch.clientY - vertex.top
};
}
return { x: e.offsetX, y: e.offsetY };
}
// 清空画布
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
关键坑点总结
- 触屏变形必加
e.preventDefault():
touchstart和touchmove都要加,缺一不可。 - 坐标要兼容触屏:
触屏用changedTouches计算相对画布坐标。 - 画笔加圆角:
lineCap:round、lineJoin:round,线条更顺滑。
效果
加了 e.preventDefault() 后:
- 快速签名不卡顿、不变形
- 圆形画得圆、线条流畅
- 触屏/鼠标完全兼容
一句话总结
不是 Canvas 难用,是没阻止浏览器默认事件!一行 e.preventDefault() 解决触屏变形大问题。
博客讲述了在前端使用canvas进行签名和指纹叠加时遇到的问题及解决方案。通过添加`e.preventDefault()`来避免触屏环境下快速签名导致的图形变形。代码示例展示了如何监听鼠标和触摸事件,实现平滑的线条绘制。
839

被折叠的 条评论
为什么被折叠?



