HTML5 Canvas是前端常用的绘图API,很多场景下我们需要让画布中的单个图形围绕指定中心旋转,但是直接调用rotate方法往往会让整个画布的所有内容都发生旋转,达不到预期效果。下面我们就来一步步讲解如何实现单个图形对象的精确旋转。

Canvas旋转的核心原理
Canvas的绘图上下文(context)维护着一套变换状态,包括平移、旋转、缩放等属性,所有的绘图操作都会受到当前变换状态的影响。rotate(angle)方法会让整个坐标系围绕原点(默认是画布左上角(0,0))旋转指定的弧度,角度转弧度的公式是 弧度 = 角度 * Math.PI / 180。
如果直接调用rotate,所有后续绘制的图形都会跟着旋转,因此要实现单个图形旋转,需要做到三点:
- 先保存当前的Canvas状态,避免影响其他图形
- 调整坐标系,让旋转中心移动到目标图形的旋转点
- 执行旋转操作后绘制目标图形,最后恢复Canvas状态
单个矩形精确旋转的实现
我们以旋转一个矩形为例,假设要让矩形围绕自身的中心点旋转30度,矩形的左上角坐标是(100,100),宽高是80和50。
实现步骤如下:
- 调用
ctx.save()保存当前画布状态 - 调用
ctx.translate(centerX, centerY)将坐标系原点平移到矩形的中心点,centerX是100+80/2=140,centerY是100+50/2=125 - 调用
ctx.rotate(30 * Math.PI / 180)执行旋转操作 - 绘制矩形时,因为坐标系已经平移,所以矩形的绘制坐标要改为相对于新原点的偏移,也就是左上角坐标是(-40, -25)(宽高的一半取负)
- 调用
ctx.restore()恢复画布状态,后续绘图不受本次旋转影响
完整的代码示例如下:
// 获取canvas元素和上下文
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
// 设置画布尺寸
canvas.width = 400;
canvas.height = 300;
// 先绘制一个不旋转的参考矩形
ctx.fillStyle = '#eee';
ctx.fillRect(100, 100, 80, 50);
// 绘制要旋转的矩形
ctx.save(); // 保存当前状态
// 矩形参数
const rectX = 100, rectY = 100;
const rectW = 80, rectH = 50;
const centerX = rectX + rectW / 2;
const centerY = rectY + rectH / 2;
const rotateAngle = 30; // 旋转30度
// 平移坐标系到矩形中心
ctx.translate(centerX, centerY);
// 执行旋转
ctx.rotate(rotateAngle * Math.PI / 180);
// 绘制矩形,坐标相对于新原点
ctx.fillStyle = 'skyblue';
ctx.fillRect(-rectW/2, -rectH/2, rectW, rectH);
ctx.restore(); // 恢复状态
// 绘制一个不受影响的圆形,验证状态已恢复
ctx.beginPath();
ctx.arc(250, 150, 30, 0, Math.PI * 2);
ctx.fillStyle = 'orange';
ctx.fill();旋转中心不是图形中心的情况
如果我们需要让图形围绕其他点旋转,比如围绕画布的左上角(0,0)旋转,只需要调整translate的参数即可。例如让上面的矩形围绕(0,0)旋转30度:
ctx.save(); // 平移到旋转中心(0,0) ctx.translate(0, 0); // 旋转30度 ctx.rotate(30 * Math.PI / 180); // 绘制矩形,此时矩形的坐标还是原来的(100,100),因为坐标系已经旋转 ctx.fillStyle = 'lightgreen'; ctx.fillRect(100, 100, 80, 50); ctx.restore();
常见注意事项
- 变换操作的顺序很重要,一定要先translate再rotate,如果先rotate再translate,平移的方向会受旋转影响,导致结果不符合预期
- 每次执行独立的图形变换前都要调用save,绘制完成后调用restore,避免变换状态互相干扰
- 如果旋转后图形位置不对,可以检查translate的偏移量是否正确,以及绘制图形时的相对坐标是否匹配平移后的坐标系
掌握以上方法后,不管是矩形、圆形还是自定义路径的图形,都可以通过调整变换顺序和参数实现精确旋转,满足各种Canvas绘图场景的需求。
HTML5_Canvascanvas旋转图形变换save_restoretranslate修改时间:2026-06-02 03:44:13