如何旋转已绘制的canvas元素并让输入坐标匹配旋转后状态?
Canvas旋转90度且交互坐标匹配的可行方案
两种方案按需选择即可:
方案一:像素重绘方案(推荐,无额外换算成本)
该方案直接将画布实际像素旋转90度,不属于CSS视觉欺骗,所有交互事件返回的坐标天然匹配显示内容,不需要额外处理。
实现步骤:
- 先通过离屏canvas暂存已经绘制完成的原画布内容,避免调整画布尺寸时内容被清空
- 互换原canvas的实际像素宽高(旋转90度后宽高会对调,注意修改的是canvas标签的
width/height属性,不是CSS宽高) - 调整绘图上下文的坐标原点、旋转角度后,把暂存的原内容绘制回画布
完整实现代码:
const canvas = document.getElementById("foobar"); const ctx = canvas.getContext("2d"); // 暂存原画布尺寸和内容 const originWidth = canvas.width; const originHeight = canvas.height; const offscreen = document.createElement('canvas'); offscreen.width = originWidth; offscreen.height = originHeight; offscreen.getContext('2d').drawImage(canvas, 0, 0); // 调整画布尺寸为旋转后的宽高 canvas.width = originHeight; canvas.height = originWidth; // 旋转绘制原内容 ctx.save(); ctx.translate(canvas.width, 0); ctx.rotate(90 * Math.PI / 180); // 要逆时针旋转就改为-90 * Math.PI / 180 ctx.drawImage(offscreen, 0, 0); ctx.restore();
执行完之后canvas的内容就是实际旋转90度的状态,后续所有点击、触摸事件直接取offsetX/offsetY使用即可,和普通canvas交互逻辑完全一致。
方案二:CSS旋转+坐标手动换算
如果不想重新绘制画布像素,可以保留CSS旋转的实现,只需要在事件回调里把原始坐标换算成旋转后的对应坐标即可。
首先修正CSS旋转的偏移问题,避免元素旋转后位置错位:
#foobar { transform-origin: top left; /* 顺时针旋转90度,同时做位移修正位置 */ transform: rotate(90deg) translate(0, -100%); }
在交互事件中按照旋转规则换算坐标即可:
canvas.addEventListener('click', (e) => { // 原始未旋转坐标系下的坐标 const rawX = e.offsetX; const rawY = e.offsetY; // 顺时针旋转90度后的对应坐标 const x = canvas.height - rawY; const y = rawX; // 后续交互逻辑统一使用换算后的x、y即可匹配视觉上的点击位置 console.log('实际点击位置坐标:', x, y); });
如果使用逆时针旋转90度,把CSS里的旋转角度改为-90deg,坐标换算公式替换为const x = rawY; const y = canvas.width - rawX;即可。
内容的提问来源于stack exchange,提问作者kuizeo
相关产品推荐
相关产品推荐

