You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Canvas下落小球实现旋转动画?

Canvas小球旋转的正确实现方法

直接调用ctx.rotate()没生效的核心原因是:Canvas的旋转默认绕坐标系原点(画布左上角)进行,而非小球自身中心。要实现小球绕自身旋转,需按以下逻辑调整绘制流程:

正确绘制步骤

  1. 保存画布状态:用ctx.save()留存当前坐标系、样式等状态,避免干扰后续绘制。
  2. 平移坐标系到小球中心:通过ctx.translate(this.x, this.y)将坐标系原点移至小球的中心位置。
  3. 执行旋转操作:此时调用ctx.rotate(this.angle * Math.PI / 180),旋转基准点即为小球中心。
  4. 以新原点绘制小球:绘制时将小球中心设为(0,0),因为坐标系已平移至小球的(x,y)位置。
  5. 恢复画布状态:用ctx.restore()回到初始坐标系状态,防止影响后续元素绘制。

修改后的Ball类代码示例

class Ball {
  constructor(ctx, x, y, radius, color) {
    this.ctx = ctx;
    this.x = x;
    this.y = y;
    this.radius = radius;
    this.color = color;
    this.speedY = 2;
    this.angle = 0; // 初始旋转角度
  }

  update() {
    this.y += this.speedY;
    // 底部反弹逻辑
    if (this.y + this.radius > this.ctx.canvas.height) {
      this.speedY *= -0.8;
      this.y = this.ctx.canvas.height - this.radius;
    }
  }

  draw() {
    this.ctx.save();
    
    // 平移到小球中心
    this.ctx.translate(this.x, this.y);
    // 角度转弧度后执行旋转
    this.ctx.rotate(this.angle * Math.PI / 180);
    
    // 以(0,0)为中心绘制小球
    this.ctx.beginPath();
    this.ctx.arc(0, 0, this.radius, 0, Math.PI * 2);
    this.ctx.fillStyle = this.color;
    this.ctx.fill();
    this.ctx.closePath();
    
    this.ctx.restore();
    
    // 递增角度实现持续旋转
    this.angle += 2;
  }
}

关键注意点

  • 必须先执行translate再执行rotate,否则旋转基准仍为画布左上角。
  • 绘制小球时的坐标需改为(0,0),适配平移后的坐标系。
  • 每次绘制完成后调用restore(),确保后续绘制不受当前坐标系变换影响。

内容的提问来源于stack exchange,提问作者Ivan Simonov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 20:27:25