canvas rotate() 绕左上角旋转是因为默认坐标系原点在(0,0),需先translate()移原点至图形中心,再rotate()(弧度制),最后绘图并restore()恢复状态。

canvas rotate() 为什么图形总转到左上角去了
因为 rotate() 是基于当前坐标系原点(默认是画布左上角)旋转的,不是围绕图形自身中心。直接调用 rotate() 前没移动原点,图形就会绕 (0, 0) 转,看起来像“飞走”了。
必须配合 translate() 把原点移到目标旋转中心,再旋转,再画图,最后用 restore() 撤销变换——否则后续所有绘图都会受影响。
- 先
save()保存当前状态 - 再
translate(x, y)把原点移到图形中心点 - 然后
rotate(angle),注意角度单位是弧度(不是度) - 最后用
fillRect()或beginPath()等从 (0, 0) 开始画图(此时 (0, 0) 就是你要的中心)
translate + rotate 组合顺序不能颠倒
变换顺序直接影响结果:translate 必须在 rotate 之前。如果先 rotate 再 translate,位移方向也会被旋转,导致图形跑到意外位置。
Canvas 的变换矩阵是右乘累积的,rotate() 改变的是坐标轴方向,之后的 translate() 就是在新坐标系下移动——这不是你想要的。
立即学习“前端免费学习笔记(深入)”;
ctx.save(); ctx.translate(200, 150); // 先把原点移到 (200, 150),即矩形中心 ctx.rotate(Math.PI / 4); // 再绕该点旋转 45° ctx.fillRect(-50, -30, 100, 60); // 从新原点画:宽高各100/60,中心对齐 ctx.restore();
rotate() 的角度单位是弧度,别传 45 直接当度数用
传 45 进去,实际是旋转 45 弧度 ≈ 2578°,图形会高速“打转”。常见写法:
-
Math.PI / 2→ 90° -
Math.PI / 4→ 45° -
deg * Math.PI / 180→ 任意度转弧度(建议封装成函数)
不转换就出错,且无报错提示,只看到图形异常偏移或静止不动——这是最常被忽略的隐性 bug。
多次旋转叠加时,save/restore 容易漏掉或配错
每个 save() 都要对应一个 restore(),嵌套多层变换时漏掉一个,会导致后续所有绘制都带着残留变换,调试极难定位。
更稳妥的做法是:每次旋转操作都独立包裹 save() 和 restore(),哪怕略影响性能,也比状态污染强。
另外,restore() 不会清空路径(beginPath() 还得自己调),也不会重置 fillStyle/strokeStyle——这些属于绘图样式,不在变换栈里。










