如何控制动画速度(requestAnimationFrame)?

4

我使用requestAnimationFrame(animate);函数改变文本颜色:

requestAnimationFrame(animate);

function animate(time){
  ... // change text color here
  if (offset_s < offset_e) {requestAnimationFrame(animate);}
}

offset_soffset_e表示文本颜色变化的起始和结束位置。在某些情况下,动画应持续2秒钟,但在其他情况下则为5秒钟,但是这两种情况下offset_e - offset_s可能相同。我该如何根据给定的时间(以秒/毫秒为单位)控制动画速度?


可能是 Controlling fps with requestAnimationFrame? 的重复问题。 - joews
如果你只是改变颜色,你可以使用CSS动画,它更容易控制时间。 - Luizgrs
4个回答

4

根据问题的标签,我只能看到您正在使用Canvas绘制动画,因此无法使用CSS动画或jQuery动画。

您需要通过计算时间差来控制动画的长度。

您可以参考以下示例进行操作:

function start_animate(duration) {
  var requestID;
  var startTime =null; 
  var time ;   

  var animate = function(time) {


   time = new Date().getTime(); //millisecond-timstamp

   if (startTime === null) {
        startTime = time;
   }
   var progress = time - startTime;

   if (progress < duration ) {

       if(offset_s < offset_e){
         // change text color here

       }
       requestID= requestAnimationFrame(animate);
   } 
   else{
      cancelAnimationFrame(requestID);
   }
   requestID=requestAnimationFrame(animate);
  }
  animate();
}

触发你的动画并调用 start_animate(2000) // 毫秒为单位的时长,1000毫秒=1秒


2

你需要清晰地区分不同的关注点。
运行一个单一的requestAnimationFrame,计算当前动画时间并调用所有与更新和绘制相关的函数。
然后,你的动画将由处理当前动画时间的函数(或类实例,如果你使用面向对象编程)处理。

这里有一些代码方向:

var animationTime = -1;
var _lastAnimationTime = -1;

function launchAnimation() {
    requestAnimationFrame(_launchAnimation);
}    

function _launchAnimation(time) {
    animationTime = 0;
    _lastAnimationTime = time;
    requestAnimationFrame(animate);
}

function animate(time){
  requestAnimationFrame(animate);
  var dt = time - _lastAnimationTime ;
  _lastAnimationTime = time;
  animationTime += dt;

  // here call every draw / update functions
  //  ...
  animationHandler.update(animationTime);
  animationHandler.draw(context);
}

要启动您的“引擎”,只需调用launchAnimation,然后您将拥有有效的animationTimedt来处理。
我会将animationHandler创建为AnimationHandler类的实例,该类允许添加/删除/更新/绘制动画。

0

我建议在JavaScript中使用setInterval函数。

requestAnimationFrame确实需要一些“丑陋”的计算。不相信?向上滚动,你会看到……

因此,为了使setInterval函数像rAF(requestAnimationFrame)一样方便,请将函数存储在变量内。以下是一个示例:

var gameLoop = setInterval(function() {
  update();
  draw();
  if (gameOver)
    clearInterval(gameLoop);
}, 1000/FPS);

通过给定的方法,你可以控制帧率并为你的物体选择正确的速度。

0

通常我会这样做

ES6

constructor() {
    this.draw();
}

draw() {
    const fps30 = 1000 / 30;
    const fps60 = 1000 / 60;
    window.requestAnimationFrame(() => {
        setTimeout(this.draw.bind(this), fps30);
    });
}

es5

function DrawingProgram() {
    this.draw();
}

DrawingProgram.prototype.draw = function() {
    var fps30 = 1000/30;
    var fps60 = 1000/60;
    var self = this;
    window.requestAnimationFrame(function() {
        window.setTimeout(function() {
            self.draw(); // you could also use apply/call here if you want
        }, fps30)
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接