Vue.js开发Canvas绘图应用触摸事件定位偏移300px问题求助
问题根源
你的触摸偏移问题核心是坐标计算逻辑错误:当前使用的pageX/pageY是相对于整个文档顶部的坐标,配合offsetLeft/offsetTop(仅相对于最近定位父元素的偏移)的计算方式没有考虑页面滚动、父元素定位、Canvas缩放等影响,所以会出现固定偏移量的问题。
完整修复方案
修复要点
- 重写坐标计算函数
touchPose,使用clientX/clientY结合Canvas元素的getBoundingClientRect()计算相对坐标,同时兼容Canvas CSS缩放场景 - 优化
drawLine的属性设置顺序,保证线条圆角属性生效 - 修正冗余的DOM选择逻辑,直接用Vue的ref获取Canvas实例
- 修正模板拼写错误
修复后代码
模板部分
<template> <canvas ref="Canvas" id="canvas" width="350" height="350"></canvas> </template>
逻辑部分
const Canvas = ref(null); const state = reactive({ canvas: null, isDrawing: false, X: 0, Y: 0, }) onMounted(() => { // 直接用ref获取canvas实例,不需要重复querySelector const canvas = Canvas.value const context = canvas.getContext('2d') state.canvas = context canvas.addEventListener('touchstart', beginTouchDrawing, false); canvas.addEventListener('touchmove', TouchDrawing, false); }) // 修正后的坐标计算逻辑 function touchPose(e){ if (e.touches?.length === 1) { const touch = e.touches[0] const canvasRect = touch.target.getBoundingClientRect() // 计算Canvas的缩放比例,兼容CSS自适应缩放场景 const scaleX = touch.target.width / canvasRect.width const scaleY = touch.target.height / canvasRect.height // 坐标先转视口相对,再转Canvas内部相对,乘以缩放比例得到精准绘图坐标 const x = (touch.clientX - canvasRect.left) * scaleX const y = (touch.clientY - canvasRect.top) * scaleY return [x, y] } return [0,0] } function beginTouchDrawing(event) { state.isDrawing = true const pos = touchPose(event) drawLine(pos[0], pos[1], pos[0], pos[1]) state.X = pos[0]; state.Y = pos[1]; event.preventDefault(); } function TouchDrawing(event) { if (state.isDrawing) { const pose = touchPose(event) drawLine(state.X, state.Y, pose[0], pose[1]); state.X = pose[0]; state.Y = pose[1]; event.preventDefault(); } } // 修正属性顺序,保证lineCap生效 function drawLine(X, Y, newX, newY){ const ctx = state.canvas if(!ctx) return ctx.lineWidth = 10; ctx.lineCap = 'round'; // 移到stroke之前才会对当前绘制生效 ctx.beginPath(); ctx.moveTo(X, Y); ctx.lineTo(newX, newY); ctx.stroke(); ctx.closePath(); }
内容的提问来源于stack exchange,提问作者Porfinogeneta
相关产品推荐
相关产品推荐

