Using requestAnimationFrame and a target FPS

By on

In the beginning...

People who've worked with Javascript animations before will probably know the next piece of code:
var targetFps = 25;
var loopInterval = window.setInterval(renderFrame, 1000 / targetFps);

What this does is create a loop that will run 25 times per second, which will hopefully give you your target framerate of 25 frames per second.

And They said: Do not use setInterval!

But then the powers that be thought of a new api: requestAnimatonFrame. It's basically a function that tells the browser it needs to execute something which will result in a redraw of a certain element.

We were told to set it up in a function like this:

function renderLoop(){
    // Put another iteration of renderLoop in the animation queue
    window.requestAnimationFrame(renderLoop);
    
    // Actually calculate and draw a frame
    renderFrame();
}

Yes, you're reading it correctly: it's basically a function calling itself. This will give you the best possible framerate. But what if we could combine those 2: setInterval and requestAnimationFrame?

The best of both worlds

function renderLoop(){

    var targetFps = 25;	
    
    // Combine setInterval and requestAnimationFrame in order to get a desired fps
    setInterval(function() {
        window.requestAnimationFrame(renderFrame);
    }, 1000 / targetFps);
}

And now you have a working requestAnimationFrame setup with a target fps!

So, what do you think?

A requestAnimationFrame polyfill

Warning: you will probably want to use a fallback function. Current fallback functions default to setInterval itself, which is not what we want.

Here's a very basic one you can use:

window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function(/* function */ callback, /* DOMElement */ element){

            // Since our requestAnimFrame is already in a loop in order to
            // control the preferred FPS, just call callback, not an interval
            callback();
          };
})();

Comments

You do not have to use a string for the callback, you can use it like here: https://github.com/mctteam/mct/blob/934446c7ac6a77a1b291f2794c15e69c97803cf4/lib/display/change.js#L26 (the "global." prefix for setTimeout is a special, more accurate timer function, it works like setTimeout)
Name
Email
Website
Body
submit error done Busy
Jelle De Loecker