Canvas 个动画 运行 同时使用 rAF 和 setInterval

Canvas animations running at the same time using both rAF and setInterval

我有一个包含不同组件的动画。

  1. 一个人走路
  2. 充满腔室的气体

这些组件中的每一个在单独使用时都运行良好,但是当我尝试将两者结合使用时,动画根本无法运行。

动画的当前状态,气体正常工作。然而,这个人在视线中忽隐忽现,有时他无处可见。

这里的问题是您每 200 毫秒绘制一次人,但是 canvas 的其余部分是在浏览器准备好后立即绘制的,由于 requestAnimationFrame(paint);,这将清除那个人。

解决方法如下: - 将你的助行器的所有绘画内容移动到 paint() 函数中 - 将所有变量的声明从 animationFramesdy 移动到 walker() 函数之外,您希望它们是全局的而不是函数内的局部变量(因为您将绘制画中人 ()-函数)

而不是同时使用requestAnimationFramesetInterval...

requestAnimationFrame (rAF) 会产生更好的性能,因为它会尝试将绘图与浏览器刷新周期同步。

因此,如果将所有动画都放在 requestAnimationFrame 中,性能会更好。

您可以使用单个 rAF 来驱动所有动画,方法是为每个动画创建一个对象(一个人对象和一个气体对象)。

每个对象包含:

  • 当前动画状态(足够的信息来绘制对象)。

  • 此动画的频率和更新下一帧动画所需的数据

这是一个示例,它每 167 毫秒为一个矩形制作动画,每

制作一个圆

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var actions=[];
//
actions.push({
  nextTime:0,
  delay:1000/60*10,
  fn:rect,
  dx:1,
  dy:1,
  x:20,
  y:20,
  options:{w:20,h:15,angle:0,fill:'skyblue'}
});
//
actions.push({
  nextTime:0,
  delay:1000/60*3,
  fn:circle,
  dx:-1,
  dy:1,
  x:200,
  y:25,
  options:{r:12,fill:'lightsalmon'}
});

requestAnimationFrame(animate);

var c=0;

function animate(time){

  ctx.clearRect(0,0,cw,ch);

  for(var i=0;i<actions.length;i++){
    var a=actions[i];
    a.fn(a);
    if(time>a.nextTime){
      a.nextTime=time+a.delay;
      a.x+=a.dx;
      a.y+=a.dy;
    }
  }

  requestAnimationFrame(animate);

}

function rect(r){
  ctx.fillStyle=r.options.fill;
  ctx.fillRect(r.x,r.y,r.options.w,r.options.h);
}

function circle(c){
  ctx.beginPath();
  ctx.arc(c.x,c.y,c.options.r,0,Math.PI*2);
  ctx.closePath();
  ctx.fillStyle=c.options.fill;
  ctx.fill();
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>