使用canvas实现在线签名(鼠标、触屏)

博客讲述了在前端使用canvas进行签名和指纹叠加时遇到的问题及解决方案。通过添加`e.preventDefault()`来避免触屏环境下快速签名导致的图形变形。代码示例展示了如何监听鼠标和触摸事件,实现平滑的线条绘制。

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);
}

关键坑点总结

  1. 触屏变形必加 e.preventDefault()
    touchstarttouchmove 都要加,缺一不可
  2. 坐标要兼容触屏
    触屏用 changedTouches 计算相对画布坐标。
  3. 画笔加圆角
    lineCap:roundlineJoin:round,线条更顺滑。

效果

加了 e.preventDefault() 后:

  • 快速签名不卡顿、不变形
  • 圆形画得圆、线条流畅
  • 触屏/鼠标完全兼容

一句话总结

不是 Canvas 难用,是没阻止浏览器默认事件!一行 e.preventDefault() 解决触屏变形大问题。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Litluecat

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值