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

时间:2015-03-07 20:46:04

标签: javascript html5 animation html5-canvas

我有一个动画,它有不同的组件。

  1. 一个人走路
  2. 气体填充腔室
  3. 这些组件中的每一个在它们独立时都能很好地工作,但是当我尝试将两者合并时,动画根本就不起作用。

    动画的当前状态,气体正常工作。然而,这个男人在视线中闪烁,在某些时候他无处可见。

2 个答案:

答案 0 :(得分:2)

而不是同时使用requestAnimationFramesetInterval ...

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

因此,如果将所有动画放在requestAnimationFrame内,效果会更好。

您可以使用单个rAF通过为每个动画(man对象和gas对象)创建对象来驱动所有动画。

每个对象都有:

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

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

这是一个示例,每隔167ms动画一个矩形,每个

一个圆圈

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>

答案 1 :(得分:0)

这里的问题是你每隔200毫秒绘制一个人,但是一旦浏览器准备好就会绘制画布的其余部分,因为requestAnimationFrame(paint);会清除该人。

解决方案:   - 将步行者的所有绘画内容移动到paint() - 函数中   - 将所有变量的声明从animationFrames移动到dy到walker() - 函数外部,你希望它们是全局的而不是函数内的本地变量(因为你将绘制男人在油漆() - 功能)