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

JavaScript Canvas:如何持续旋转画布绘制的图像?

嘿,这个问题我当初刚接触canvas时也踩过坑!canvas的旋转是绕坐标系原点来的,直接调用rotate()的话你的sprite会“飞”出去,得用坐标系平移的小技巧来让它原地转。结合你说的setInterval方案,给你整一套完整的实现思路和代码:

核心逻辑(敲黑板)

要让sprite在原地旋转,关键是调整坐标系的位置,步骤拆解:

  • 先把画布坐标系平移到sprite的中心位置
  • 旋转坐标系
  • 以新的坐标系原点为中心绘制sprite
  • 最后把坐标系恢复原样,避免影响后续其他绘制操作
完整代码实现

HTML部分

<canvas id="myCanvas" width="400" height="400"></canvas>

JavaScript部分

// 获取画布和绘图上下文
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// 定义你的Sprite属性(如果是图片,这里可以添加img对象提前加载)
const sprite = {
  x: 150,          // Sprite左上角的x坐标
  y: 150,          // Sprite左上角的y坐标
  width: 100,      // Sprite宽度
  height: 100,     // Sprite高度
  rotation: 0,     // 当前旋转角度(度数)
  // img: new Image() // 如果是图片Sprite,记得提前加载完成再启动动画
};

// 绘制旋转Sprite的核心函数
function drawRotatedSprite() {
  // 清空画布,避免之前的帧残留
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 保存当前画布状态(平移、旋转会修改状态,用完必须恢复)
  ctx.save();

  // 1. 把坐标系平移到Sprite的中心位置
  ctx.translate(sprite.x + sprite.width / 2, sprite.y + sprite.height / 2);

  // 2. 旋转坐标系(注意要把度数转成弧度,Math.PI/180是转换系数)
  ctx.rotate(sprite.rotation * Math.PI / 180);

  // 3. 绘制Sprite:此时坐标系中心在Sprite中心,所以要向左上偏移自身宽高的一半
  // 如果是图片,替换成 ctx.drawImage(sprite.img, -sprite.width/2, -sprite.height/2, sprite.width, sprite.height)
  ctx.fillStyle = 'red';
  ctx.fillRect(-sprite.width / 2, -sprite.height / 2, sprite.width, sprite.height);

  // 4. 恢复之前保存的画布状态,避免影响后续绘制
  ctx.restore();
}

// 用setInterval每300ms更新旋转角度并重绘
setInterval(() => {
  // 每次增加10度,你可以调整这个值控制旋转速度
  sprite.rotation += 10;
  // 角度超过360后重置,避免数值无限增大
  if (sprite.rotation >= 360) {
    sprite.rotation = 0;
  }
  drawRotatedSprite();
}, 300);
额外优化建议

如果追求更流畅的动画效果,更推荐用requestAnimationFrame替代setInterval——它会和浏览器的刷新频率同步,避免卡顿。如果要保留300ms的更新间隔,可以加个时间戳判断:

let lastUpdateTime = 0;
function animate(timestamp) {
  if (timestamp - lastUpdateTime >= 300) {
    sprite.rotation += 10;
    if (sprite.rotation >= 360) sprite.rotation = 0;
    lastUpdateTime = timestamp;
  }
  drawRotatedSprite();
  requestAnimationFrame(animate);
}
// 启动动画
requestAnimationFrame(animate);

内容的提问来源于stack exchange,提问作者Ben Foster

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:48:51