移动端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
相关产品推荐
相关产品推荐

