[ACCEPTED]-How to use requestAnimationFrame?-requestanimationframe

Accepted answer
Score: 83

Warning! This question is not about the best way to shim requestAnimFrame. If you are looking for that, move on to any other answer on this page.


You got tricked by automatic semicolon 18 insertion. Try this:

window.requestAnimFrame = function(){
    return (
        window.requestAnimationFrame       || 
        window.webkitRequestAnimationFrame || 
        window.mozRequestAnimationFrame    || 
        window.oRequestAnimationFrame      || 
        window.msRequestAnimationFrame     || 
        function(/* function */ callback){
            window.setTimeout(callback, 1000 / 60);
        }
    );
}();

javascript automatically 17 puts a semicolon behind your return statement. It 16 does this because it is followed by a newline 15 and the next line is a valid expression. In 14 fact it gets translated to:

return;
window.requestAnimationFrame       || 
window.webkitRequestAnimationFrame || 
window.mozRequestAnimationFrame    || 
window.oRequestAnimationFrame      || 
window.msRequestAnimationFrame     || 
function(/* function */ callback){
    window.setTimeout(callback, 1000 / 60);
};

This code returns 13 undefined and never executes the code behind the 12 return statement. So window.requestAnimFrame is undefined. When you call 11 it in animloop, the javascript produces an error 10 and stops execution. You can solve the problem 9 by enclosing the expression in parentheses.

May 8 I recommend the Chrome developer tools or 7 firebug to inspect javascript execution. With 6 these tools you would have seen the error. You 5 should go about debugging it as follows 4 (I'm assuming Chrome):

  1. Execute the code (it produces unexpected results)
  2. Open the developer tools (right click -> Inspect Element) You will see a red x in the status bar at the right (this means there is an error in the execution)
  3. Open the console tab
  4. You will see
    Uncaught TypeError: Property 'requestAnimFrame' of object [object DOMWindow] is not a function
  5. Type in the console: window.requestAnimFrame and press enter, you will see it is undefined. By now you know that the problem is in fact unrelated to requestAnimationFrame and that you should concentrate on the first part of your code.
  6. Now it is a matter of narrowing down the code up to the point where it returns something. This is the difficult part and if you still don't find it at this point you might want to turn to the internet for more help.

Also, watch this video for some 3 good practices in writing javascript, He 2 also mentions the evil automatic semicolon 1 insertion.

Score: 8
 /*
  Provides requestAnimationFrame in a cross browser way.
  http://paulirish.com/2011/requestanimationframe-for-smart-animating/
 */

if (!window.requestAnimationFrame) {

    window.requestAnimationFrame = (function() {

        return window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame || // comment out if FF4 is slow (it caps framerate at ~30fps: https://bugzilla.mozilla.org/show_bug.cgi?id=630127)
        window.oRequestAnimationFrame ||
            window.msRequestAnimationFrame ||
            function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element) {

                window.setTimeout(callback, 1000 / 60);

        };

    })();

}

animate();

function animate() {
    requestAnimationFrame(animate);
    draw();
}

function draw() {
    // Put your code here
}

Have a look at the below jsfiddle example; It 2 illustrates clearly what I mean;

http://jsfiddle.net/XQpzU/4358/light/

Hope this 1 helps!

Score: 0

"Smart throttling so the event won't get 2 fired more times than the screen can repaint 1 the change:

var requestFrame = window.requestAnimationFrame ||
                   window.webkitRequestAnimationFrame ||
                   // polyfill - throttle fall-back for unsupported browsers
                   (function() {
                       var throttle = false,
                           FPS = 1000 / 60; // 60fps (in ms)
       
                       return function(CB) {
                         if( throttle ) return;
                         throttle = true;
                         setTimeout(function(){ throttle = false }, FPS);
                         CB(); // do your thing
                       }
                    })();

/////////////////////////////
// use case:

function doSomething() {
  console.log('fired');
}

window.onscroll = function() {
  requestFrame(doSomething);
};
html, body{ height:300%; }
body::before{ content:'scroll here'; position:fixed; font:2em Arial; }

More Related questions