CSS旋转90deg后Canvas strokeRect鼠标坐标偏移问题求助
解决Canvas CSS旋转后鼠标绘图坐标错位问题
问题本质
CSS的transform: rotate(90deg)仅对Canvas元素做视觉层面的旋转,Canvas自身的绘图坐标系(原点在左上角,x轴向右、y轴向下)并未改变。但鼠标事件的clientX/clientY是基于浏览器窗口的坐标,直接映射到Canvas原坐标系就会出现错位。
核心解决方案:坐标矩阵转换
利用Canvas的getScreenCTM()获取包含CSS变换的矩阵,再通过逆矩阵将鼠标坐标转换为Canvas本地坐标系的正确位置:
坐标转换函数
function getCanvasLocalPos(canvas, clientX, clientY) { const rect = canvas.getBoundingClientRect(); // 获取变换矩阵的逆矩阵,用于将屏幕坐标转回Canvas本地坐标 const inverseMatrix = canvas.getScreenCTM().inverse(); // 创建鼠标相对于Canvas元素的坐标点 const mousePoint = new DOMPoint(clientX - rect.left, clientY - rect.top); // 应用逆矩阵转换 const localPoint = mousePoint.matrixTransform(inverseMatrix); return { x: localPoint.x, y: localPoint.y }; }
在鼠标事件中使用
在mousedown、mousemove等事件里,替换原来的坐标计算逻辑:
canvas.addEventListener('mousedown', (e) => { const { x, y } = getCanvasLocalPos(canvas, e.clientX, e.clientY); // 用转换后的x、y作为矩形起始点 startX = x; startY = y; });
替代方案:使用Canvas自身坐标系旋转
如果不想用CSS变换,直接操作Canvas上下文的坐标系:
- 调整Canvas宽高(旋转90度后宽高互换)
- 重设上下文变换:
const ctx = canvas.getContext('2d'); // 保存原状态 ctx.save(); // 平移到画布中心 ctx.translate(canvas.width / 2, canvas.height / 2); // 旋转90度(Math.PI/2 对应90度) ctx.rotate(Math.PI / 2); // 平移回原点,确保绘图原点对齐视觉左上角 ctx.translate(-canvas.height / 2, -canvas.width / 2); // 此时绘图会自动应用旋转,鼠标坐标也需要对应转换: // 旋转90度后,原(x,y)对应新坐标为 (canvas.height - y, x) ctx.restore(); // 结束后可恢复原状态
关键注意事项
- 避免混用CSS变换和Canvas上下文变换,两种方式的坐标转换逻辑完全不同
getBoundingClientRect()返回的是旋转后的元素可视尺寸,而Canvas的width/height属性是绘图缓冲区的原始尺寸,两者不能混淆
内容的提问来源于stack exchange,提问作者mammoth
相关产品推荐
相关产品推荐

