Javascript - Can't Adjust FrameRate - requestanimationframe

Lumo5 picture Lumo5 · Sep 25, 2013 · Viewed 11k times · Source

I start the loop

function gameLoop(){
   update();
   draw();
   requestAnimFrame(gameLoop);
}

var requestAnimFrame =  window.requestAnimationFrame ||
                    window.webkitRequestAnimationFrame ||
                    window.mozRequestAnimationFrame ||
                    window.oRequestAnimationFrame ||
                    window.msRequestAnimationFrame ||
                    function(callback) {
                        window.setTimeout(callback, 1000 / 1);
                    };
  1. I can't adjust the frame rate. It is always really fast. Why can't I change it to 1 frame a second. I want to do this just for testing purposes.
  2. Do I have to clear the canvas each time? It seems to work good without clearing it.

Thanks.

Here is a link to a fiddle for the complete code: complete code

Thanks

Answer

user1693593 picture user1693593 · Sep 25, 2013

rAF is locked to monitor's sync, typically 60 Hz, so we can't adjust the FPS for it in itself (browser may reduce FPS when tab is inactive or on batteries).

Also, what you are trying to change is the fallback for the poly-fill; that is: if rAF is not supported in the browser it will instead use setTimeout. However, most browsers nowadays do support rAF (even un-prefixed) so the setTimeout will never be used.

You can do two things:

  • Replace rAF in your loop by using setTimeout directly (when testing)

Example:

var FPS = 1;

function testLoop() {

    ... ordinary code

    setTimeout(testLoop, 1000/FPS);
}
  • Throttle rAF by using a counter:

Example:

var framesToSkip = 60,
    counter = 0;

function loop() {

    if (counter < framesToSkip) {
        counter++;
        requestAnimationFrame(loop);
        return;
    }

    /// do regular stuff

    counter = 0;
    requestAnimationFrame(loop);
}

MODIFIED FIDDLE HERE

There are most likely better ways to implement throttling, but I am trying to just show the basic principle. This will still run at full speed, 60 FPS, but your code will do minimal of operations and only when the counter has reached its count will it execute the main code.

You do not need to clear the canvas each time if what you draw next will cover previously drawn content, or if you want to keep it of course. You can also clear a portion to optimize further, if needed.