canvas旋转默认绕左上角原点,需先用translate将旋转中心移至原点,再rotate,最后restore恢复;绕中心旋转时translate(x+w/2,y+h/2),绘制坐标偏移为(-w/2,-h/2)。

Canvas图形旋转默认绕原点(0,0)进行,若不调整坐标系,图形会“飞出画布”或偏离预期位置。要让图形围绕自身中心、某角点或任意指定位置旋转,平移变换(translate)是关键前置步骤——它负责把旋转轴心“搬”到坐标原点,再执行rotate,最后再“搬回去”(通常靠restore自动处理)。
为什么必须先平移?
Canvas的rotate()方法只接受一个弧度参数,它始终围绕当前坐标系原点旋转。这个原点默认在画布左上角(0,0),而不是图形中心。如果你直接调用ctx.rotate(0.5)后画一个矩形,它会以(0,0)为圆心甩出去,而非绕自己转。
解决办法就是:用translate把图形的期望旋转中心点移到(0,0),此时再rotate,图形就自然绕该点旋转;绘制完成后restore,坐标系恢复,不影响后续操作。
围绕图形中心旋转的标准流程
以宽w、高h的矩形为例,想让它绕自身中心旋转:
- 调用ctx.save()保存当前状态
- 用ctx.translate(x + w/2, y + h/2)把旋转中心(即矩形中心)移到原点
- 调用ctx.rotate(angle),此时rotate作用于新原点
- 用ctx.fillRect(-w/2, -h/2, w, h)从中心向四周绘制(注意坐标偏移)
- 调用ctx.restore()恢复原始坐标系
支持任意旋转点的灵活写法
旋转中心不限于中心,也可以是左上角、右下角或任意像素点(如x=100, y=80):
- 想绕左上角旋转?直接ctx.translate(x, y),然后drawRect(0, 0, w, h)
- 想绕右下角旋转?ctx.translate(x + w, y + h),再drawRect(-w, -h, w, h)
- 想绕自定义点(px, py)?ctx.translate(px, py),再按相对位置绘制(如图像用drawImage(img, -img.width/2, -img.height/2))
常见误区与注意事项
平移和旋转顺序不能颠倒——必须先translate再rotate,否则rotate仍作用于旧原点。
- rotate的单位是弧度,不是度数。常用换算:angleRad = angleDeg * Math.PI / 180
- 多次连续rotate会叠加角度,建议每次独立使用save/restore隔离
- 如果图形缩放后旋转,scale也会影响坐标系,需注意translate的数值是否已受缩放影响
- 动画中每帧重绘前,务必clearRect清空画布,否则旧图形残留











