javascriptcanvastimeframe-raterequestanimationframe

How to get the time difference between window.requestAnimationFrame calls?


What is the best way to get the time difference between window.requestAnimationFrame callback in javascript?

I have tried:

// create the best .requestAnimationFrame callback for each browser
window.FPS = (function() {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {window.setTimeout(callback, 1000 / 60);};
})();

// start animation loop
var dt, stamp = (new Date()).getTime();
function loop() {
    window.FPS(loop);
    var now = (new Date()).getTime();
    var dt = now - stamp;
    stamp = now;
}
// has "dt" the best accuracy?

Solution

  • Most modern browsers automatically send in a high-precision timestamp as an argument into each requestAnimation callback loop: http://caniuse.com/#search=performance

    So you simply subtract the last timestamp from the current timestamp to get the elapsed time since the loop was last run.

    Here's example code and a Demo:

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var cw=canvas.width;
    var ch=canvas.height;
    
    var startingTime;
    var lastTime;
    var totalElapsedTime;
    var elapsedSinceLastLoop;
    
    var $total=$('#total');
    var $loop=$('#loop');
    
    requestAnimationFrame(loop);
    
    function loop(currentTime){
      if(!startingTime){startingTime=currentTime;}
      if(!lastTime){lastTime=currentTime;}
      totalElapsedTime=(currentTime-startingTime);
      elapsedSinceLastLoop=(currentTime-lastTime);
      lastTime=currentTime;
      $total.text('Since start: '+totalElapsedTime+' ms');
      $loop.text('Since last loop: '+elapsedSinceLastLoop+' ms');
      requestAnimationFrame(loop);
    }
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <p id=total>T1</p>
    <p id=loop>T2</p>
    <canvas id="canvas" width=300 height=300></canvas>

    For the couple of browsers that don't support Performance, you will have to use Date.now() instead of currentTime inside the loop since no timestamp is automatically sent by those browsers into the loop.