canvas中rotate()默认绕(0,0)旋转,要绕指定点(cx,cy)旋转需先translate(cx,cy),再rotate(弧度),最后translate(-cx,-cy),并推荐用save()/restore()保护坐标系状态。

在 HTML5 Canvas 中,rotate() 方法默认围绕画布原点(左上角,即坐标 (0, 0))旋转整个坐标系。若想围绕**指定中心点**(如 (cx, cy))旋转图形,需通过「平移—旋转—反向平移」三步组合实现,本质是坐标系变换。
核心步骤:平移 → 旋转 → 反向平移
Canvas 的变换操作作用于当前坐标系,不是单个图形。要让某图形绕其中心旋转,需:
-
先将坐标系原点移到目标中心点(用
translate(cx, cy)) -
再执行旋转(此时
rotate(angle)就是以新原点为中心) -
最后把原点移回原来位置(用
translate(-cx, -cy))
⚠️ 注意:角度单位是弧度,不是度数。可将角度转为弧度:angle * Math.PI / 180。
实际代码示例:绕 (100, 100) 旋转一个矩形
以下代码绘制一个以 (100, 100) 为中心、宽高各 60 的矩形,并绕该点逆时针旋转 30°:
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
<p>// 保存当前坐标系状态(推荐,避免影响后续绘图)
ctx.save();</p><p>// 步骤1:把原点移到旋转中心 (100, 100)
ctx.translate(100, 100);</p><p>// 步骤2:旋转坐标系(30° → 弧度)
ctx.rotate(30 * Math.PI / 180);</p><p>// 步骤3:绘制图形——此时 (0, 0) 就是原 (100, 100),所以画在 (-30, -30) 开始,宽高 60
ctx.fillStyle = 'blue';
ctx.fillRect(-30, -30, 60, 60);</p><p>// 恢复之前坐标系(含平移和旋转的撤销)
ctx.restore();
</p>
关键细节与常见误区
- 变换顺序不可颠倒:必须 translate → rotate → 绘图;若先 rotate 再 translate,旋转中心仍是 (0, 0)
-
使用
save()和restore()非常重要,否则后续所有绘图都会受残留变换影响 -
旋转的是坐标系,不是图形本身:你画的每个点都按新坐标系解释,所以矩形顶点要按新原点来算(如上例中用
(-30,-30)表示中心对齐) - 若要旋转多个不同中心的图形,每次都要独立做 save → translate → rotate → draw → restore
封装成可复用函数(可选)
为简化操作,可封装一个围绕中心点旋转并绘制的辅助函数:
function rotateAt(ctx, cx, cy, angle, drawFn) {
ctx.save();
ctx.translate(cx, cy);
ctx.rotate(angle);
ctx.translate(-cx, -cy); // 可选:若 drawFn 内部按绝对坐标画,这步可省;但通常更推荐下一步直接在 (0,0) 附近画
drawFn(ctx);
ctx.restore();
}
<p>// 使用示例
rotateAt(ctx, 100, 100, 45 * Math.PI / 180, (g) => {
g.fillStyle = 'red';
g.fillRect(70, 70, 60, 60); // 这里仍可用原始坐标,因已 translate(-cx,-cy)
});
</p>
不过更清晰的做法仍是统一用「以中心为 (0,0)」的方式绘制(如第一个示例),逻辑更直观稳定。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











