You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用jQuery开发HTML5 Canvas绘图工具遇到的两类异常求解

修复方案

问题根因

  1. 桌面端绘制不停止:mouseup事件绑定选择器写错,事件从未触发,isPressed状态一直为true
  2. 移动端触摸异常:触摸事件名称拼写错误,且新触摸时没有重置上一次绘制坐标,导致线条异常连接

具体修改点

  • 修正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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 20:36:04