Canvas CSS尺寸与实际宽高不匹配画笔偏移,如何保留小画布同时维持高画质
问题解决方法
核心原因
你遇到的坐标偏移问题本质是Canvas的实际像素尺寸(即width/height属性定义的960540)和CSS展示尺寸(定义的284120)不匹配导致的:鼠标/触摸事件返回的坐标是相对于显示尺寸的相对值,直接用在实际尺寸更大的画布上自然会出现位置偏移。
解决方案
只需要给所有获取到的屏幕坐标乘以对应的缩放系数,把屏幕坐标转换为画布实际像素坐标即可,不需要修改画布本身的尺寸定义,即可同时保留小展示尺寸和高分辨率画质。
具体修改步骤
- 先计算宽高的缩放比例:
- 宽缩放比 = 画布实际宽度 / 画布展示宽度
- 高缩放比 = 画布实际高度 / 画布展示高度
- 所有鼠标、触摸事件获取的坐标都乘以对应的缩放比再传入绘制逻辑
修改后的代码片段
1. 修改触摸坐标获取函数getTouchPoint
const getTouchPoint = evt => { if (!evt.currentTarget) { return [0, 0]; } const rect = evt.currentTarget.getBoundingClientRect(); const touch = evt.targetTouches[0]; // 新增缩放比例计算 const scaleX = canvas2.width / rect.width; const scaleY = canvas2.height / rect.height; return [ (touch.clientX - rect.left) * scaleX, (touch.clientY - rect.top) * scaleY ]; };
2. 修改鼠标事件的坐标处理
const mouseMove = evt => { if (!drawing) { return; } const rect = canvas2.getBoundingClientRect(); const scaleX = canvas2.width / rect.width; const scaleY = canvas2.height / rect.height; continueStroke([evt.offsetX * scaleX, evt.offsetY * scaleY]); }; const mouseDown = evt => { if (drawing) { return; } evt.preventDefault(); canvas2.addEventListener("mousemove", mouseMove, false); const rect = canvas2.getBoundingClientRect(); const scaleX = canvas2.width / rect.width; const scaleY = canvas2.height / rect.height; startStroke([evt.offsetX * scaleX, evt.offsetY * scaleY]); };
额外优化建议
如果担心窗口缩放、画布尺寸变化导致缩放比不准,可以把缩放比计算抽成公共函数,每次获取坐标时动态计算即可,不需要额外监听resize事件。
内容的提问来源于stack exchange,提问作者Nash
相关产品推荐
相关产品推荐

