You need to enable JavaScript to run this app. 移动端Canvas画布无法绘制如何解决?附相关JS实现代码
优惠活动
大模型
产品
解决方案
定价
更多

移动端Canvas画布无法绘制如何解决?附相关JS实现代码

Canvas移动端无法绘制解决方案

问题核心原因

你的代码仅完成了桌面端鼠标交互的绘制逻辑,触摸相关逻辑存在以下缺失:

  • 仅声明了空的ontouchstart回调,没有绑定touchstart、touchmove、touchend三个核心触摸事件的处理逻辑
  • 触摸事件触发时没有同步更新触点坐标到你声明的mouse变量,也没有触发绘制流程
  • 触摸操作默认会触发页面滚动、缩放等系统行为,会干扰画布绘制,需要主动阻止默认行为

完整修改后的代码

let configureCanvas = canvas => {
  let ctx = canvas.getContext("2d");
  let painting = canvas.parentNode;
  let paintStyle = getComputedStyle(painting);


  if(canvas == document.getElementById("pizarra-musculos")) {
      var x = window.matchMedia("(max-width: 700px)")
      myFunction(x) // Call listener function at run time
      x.addListener(myFunction) // Attach listener function on state changes 
      function myFunction(x) {
      if (x.matches) { // If media query matches
          canvas.width = "350";
          canvas.height = "350";
        } else {
          canvas.width = "500";
          canvas.height = "500";
        }
      }
  }else{
    canvas.width = "350";
    canvas.height = "350";
  }


  let mouse = {
    x: 0,
    y: 0
  };

  // 复用坐标更新逻辑,鼠标和触摸事件通用
  function updatePosition(clientX, clientY, targetCanvas) {
    mouse.x = clientX - targetCanvas.offsetLeft;
    mouse.y = clientY - targetCanvas.offsetTop;
  }

  // 触摸事件处理
  canvas.addEventListener('touchstart', function(e) {
    e.preventDefault(); // 阻止默认滚动/缩放行为
    const touch = e.touches[0];
    updatePosition(touch.pageX, touch.pageY, this);
    ctx.beginPath();
    ctx.moveTo(mouse.x, mouse.y);
    canvas.addEventListener('touchmove', onPaint, false);
  }, false);

  canvas.addEventListener('touchmove', function(e) {
    e.preventDefault();
    const touch = e.touches[0];
    updatePosition(touch.pageX, touch.pageY, this);
  }, false);

  canvas.addEventListener('touchend', function() {
    canvas.removeEventListener('touchmove', onPaint, false);
  }, false);

  // 原有鼠标事件逻辑
  canvas.addEventListener('mousemove', function(e) {
    updatePosition(e.pageX, e.pageY, this);
  }, false);

  if(canvas == document.getElementById("pizarra-musculos")) {
     //Rojo Claro
    ctx.lineWidth = 12;
    ctx.lineJoin = 'round';
    ctx.lineCap = 'round';
    ctx.strokeStyle = 'rgba(255, 8, 53, 0.02)';

    document.getElementById("btnRojoClaro").addEventListener("click", ()=>{
      //Rojo Claro
      ctx.lineWidth = 12;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = 'rgba(255, 8, 53, 0.02)';
    });
    document.getElementById("btnVerde").addEventListener("click", ()=>{
      //Verde
      ctx.lineWidth = 4;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = '#249120';
    });
    document.getElementById("btnRojo").addEventListener("click", ()=>{
      //Rojo
      ctx.lineWidth = 4;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = '#ff0000';
    });
    document.getElementById("btnNegro").addEventListener("click", ()=>{
      //Negro
      ctx.lineWidth = 4;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = '#000000';
    });
    document.getElementById("btnAzul").addEventListener("click", ()=>{
      //Azul
      ctx.lineWidth = 4;
      ctx.lineJoin = 'round';
      ctx.lineCap = 'round';
      ctx.strokeStyle = '#1e5085';
    });


  }else{
    ctx.lineWidth = 3;
    ctx.lineJoin = 'round';
    ctx.lineCap = 'round';
   ctx.strokeStyle = '#e34f54';
  };

  canvas.addEventListener('mousedown', function(e) {
    ctx.beginPath();
    ctx.moveTo(mouse.x, mouse.y);
    canvas.addEventListener('mousemove', onPaint, false);
  }, false);

  canvas.addEventListener('mouseup', function() {
    canvas.removeEventListener('mousemove', onPaint, false)
  }, false);

  var onPaint = function() {
    ctx.lineTo(mouse.x, mouse.y);
    ctx.stroke();
  };

  canvas.nextElementSibling.addEventListener('click', function() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
  });


}

其他注意事项

如果页面有缩放配置,建议在html头部添加viewport元标签,保证坐标计算准确:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

内容的提问来源于stack exchange,提问作者Leonel Gabriel Wetzel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 10:15:02