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

如何解决Javascript Canvas绘图代码在移动端浏览器无法运行的问题

问题原因

移动端touch事件的触点坐标不会直接挂载在event对象根属性上,单指操作时需要从event.touches[0]对象中读取clientX、clientY,你当前代码直接读取根event的坐标在touch事件触发时拿到的是undefined,自然无法绘制。

修复方案

在start、draw函数中先判断事件类型,优先取touch事件的触点坐标,再 fallback 到鼠标事件的坐标即可,修复后完整代码如下:

const canvas = document.getElementById("draw");
canvas.width = window.innerWidth - 60;
canvas.height = 400;

let context = canvas.getContext("2d");
context.fillStyle = "white";
context.fillRect(0, 0, canvas.width, canvas.height);

let draw_color = "black";
let draw_width = "2";
let is_drawing = false;

canvas.addEventListener("touchstart", start, false);
canvas.addEventListener("touchmove", draw, false);
canvas.addEventListener("mousedown", start, false);
canvas.addEventListener("mousemove", draw, false);

canvas.addEventListener("touchend", stop, false);
canvas.addEventListener("mouseup", stop, false);
canvas.addEventListener("mouseout", stop, false);

// 统一获取坐标的工具函数
function getEventPos(event) {
    // 优先取touch事件的第一个触点坐标
    if(event.touches && event.touches.length > 0) {
        return {
            x: event.touches[0].clientX - canvas.offsetLeft,
            y: event.touches[0].clientY - canvas.offsetTop
        }
    }
    // 鼠标事件直接取根属性
    return {
        x: event.clientX - canvas.offsetLeft,
        y: event.clientY - canvas.offsetTop
    }
}

function start(event) {
    is_drawing = true;
    context.beginPath();
    const pos = getEventPos(event)
    context.moveTo(pos.x, pos.y);
    event.preventDefault();
}


function draw(event) {
    if (is_drawing) {
        const pos = getEventPos(event)
        context.lineTo(pos.x, pos.y);
        context.strokeStyle = draw_color;
        context.lineWidth = draw_width;
        context.lineCap = "round";
        context.lineJoin = "round";
        context.stroke();
    }
    event.preventDefault();
}

function stop(event) {
    if (is_drawing) {
        context.stroke();
        context.closePath();
        is_drawing = false;
    }
    event.preventDefault();
}

如果后续遇到绘制线条模糊的问题,可以把canvas的宽高属性乘以window.devicePixelRatio,再用CSS把canvas的显示尺寸设置回原来的数值即可解决。

内容的提问来源于stack exchange,提问作者TEN_KUNG

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 14:45:03