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

Posted

技术标签:

【中文标题】如何控制动画速度(requestAnimationFrame)?【英文标题】:How to control animation speed (requestAnimationFrame)? 【发布时间】:2015-03-14 23:16:45 【问题描述】:

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

requestAnimationFrame(animate);

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

offset_soffset_s 指示颜色更改文本的开始和结束位置。在某些情况下,动画应该持续 2 秒,但在顺序情况下 - 持续 5 秒,但 offset_e - offset_s 在这两种情况下可能相同。我该怎么做才能根据给定的时间(以秒/毫秒为单位)控制动画的速度?

【问题讨论】:

Controlling fps with requestAnimationFrame?的可能重复 如果你只是改变颜色,你可以使用 css 动画,用它来控制时间会更容易 【参考方案1】:

从问题的标签中,我只能看到你在画布上绘制了动画,这就是为什么你不能使用 css-animation 或 jquery-animation。

你必须通过计算时间差来控制动画的长度。

你可以像这个例子一样做

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 sec

【讨论】:

【参考方案2】:

您应该清楚地区分关注点。 运行单个 requestAnimationFrame,它计算当前动画时间并调用每个更新和绘制相关函数。 然后,您的动画将由处理当前动画时间的函数(或类实例,如果您使用 OOP)处理。

只是代码的一些方向:

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 类的一个实例,它允许添加/删除/更新/绘制动画。

【讨论】:

【参考方案3】:

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

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

所以,要使setInterval 函数像 rAF(requestAnimationFrame) 一样方便,请将函数存储在变量中。这是一个例子:

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

通过特定方式,您可以控制您的 FPS 并为您的对象选择正确的速度。

【讨论】:

【参考方案4】:

我通常会做类似的事情

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)
    );

【讨论】:

以上是关于如何控制动画速度(requestAnimationFrame)?的主要内容,如果未能解决你的问题,请参考以下文章

如何控制模型/动画师 Unity 3D 的速度

帧动画插件

动画控制器中的混合树如何在动画之间平滑切换?

如何在不重复Unity动画的情况下通过Animator提高动画播放速度

控制 uitableview insertRowsAtIndexPath 动画的速度

Unity重置动画帧位置转换状态时控制播放速度