使用jQuery开发HTML5 Canvas绘图工具遇到的两类异常求解
修复方案
问题根因
- 桌面端绘制不停止:
mouseup事件绑定选择器写错,事件从未触发,isPressed状态一直为true - 移动端触摸异常:触摸事件名称拼写错误,且新触摸时没有重置上一次绘制坐标,导致线条异常连接
具体修改点
- 修正
mouseup事件绑定,移除选择器多余引号,确保松开鼠标时正确重置绘制状态 - 修正移动端触摸事件名:将
touchdown改为touchstart、touchup改为touchend - 调整
mousedown逻辑:先计算当前点击坐标,再赋值给prevX/prevY,同时直接绘制当前点,避免新点击连接旧线条 mouseup时同步重置prevX/prevY为undefined,彻底断开新旧绘制的线条连接- 补充缺失的
size变量定义 - 移动端触摸事件添加阻止默认行为,避免触发页面滚动/缩放
- 修复
touchend事件报错问题:该事件触发时手指已经离开屏幕,无需读取触摸坐标
修复后完整代码
$(document).ready(function(){ let color = "black"; // 补充缺失的画笔大小变量,可根据需求调整默认值 let size = 2; let x; let y; let isPressed = false; // 初始化绘制状态为未按下 const canvas = $("canvas"); const colorElement = $("#color"); const ctx = canvas[0].getContext("2d"); const canvass = document.getElementById("myCanvas"); ctx.canvas.width = window.innerWidth; ctx.canvas.height = window.innerHeight; let prevX,prevY; canvas.on("mousedown",(e)=>{ isPressed = true; // 先计算当前点击的坐标 x = e.pageX - ctx.canvas.offsetLeft; y = e.pageY - ctx.canvas.offsetTop; // 把上一次坐标直接设为当前坐标,避免连接旧线条 prevX = x; prevY = y; // 点击时直接画圆点,满足点触绘画需求 drawCircle(x,y); }); // 移除document选择器的多余引号 $(document).on("mouseup",(e)=>{ isPressed = false; x = undefined; y = undefined; // 同步重置上一次坐标 prevX = undefined; prevY = undefined; }); canvas.on("mousemove",(e)=>{ if(isPressed){ e.preventDefault(); e.stopPropagation(); x = e.pageX - ctx.canvas.offsetLeft; y = e.pageY - ctx.canvas.offsetTop; drawCircle(x,y); drawLine(prevX,prevY,x,y); prevX = x; prevY = y; } }); // 修正移动端触摸事件逻辑 canvass.addEventListener("touchstart", function (e) { e.preventDefault(); var touch = e.touches[0]; var mouseEvent = new MouseEvent("mousedown", { clientX: touch.clientX, clientY: touch.clientY }); canvass.dispatchEvent(mouseEvent); }, false); canvass.addEventListener("touchmove", function (e) { e.preventDefault(); var touch = e.touches[0]; var mouseEvent = new MouseEvent("mousemove", { clientX: touch.clientX, clientY: touch.clientY }); canvass.dispatchEvent(mouseEvent); }, false); canvass.addEventListener("touchend", function (e) { e.preventDefault(); // touchend时无有效触摸点,直接触发mouseup即可 var mouseEvent = new MouseEvent("mouseup", {}); canvass.dispatchEvent(mouseEvent); }, false); function drawCircle(x,y){ ctx.beginPath(); ctx.arc(x,y,size,0,Math.PI * 2); ctx.fillStyle = color; ctx.fill(); ctx.closePath(); } function drawLine(x,y,x2,y2){ // 新增坐标校验,避免无效绘制 if(x === undefined || y === undefined) return; ctx.beginPath(); ctx.moveTo(x,y); ctx.lineTo(x2,y2); ctx.strokeStyle = color; ctx.lineWidth = size*2; ctx.stroke(); ctx.closePath(); } colorElement.on("change",(e)=>{ color = e.target.value; }); });
内容的提问来源于stack exchange,提问作者amaan
相关产品推荐
相关产品推荐

