I'm new to animation, but I have recently created an animation using setTimeout
. The FPS was too low, so I found a solution to use requestAnimationFrame
, described in this link.
So far, my code is:
//shim layer with setTimeout fallback window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback){ window.setTimeout(callback, 1000 / 60); }; })(); (function animloop(){ //Get metrics var leftCurveEndX = finalLeft - initialLeft; var leftCurveEndY = finalTop + finalHeight - initialTop; var rightCurveEndX = finalLeft + finalWidth - initialLeft - initialWidth; var rightCurveEndY = leftCurveEndY; chopElement(0, 0, 0, 0, leftCurveEndX, leftCurveEndY, rightCurveEndX, rightCurveEndY);//Creates a new frame requestAnimFrame(animloop); })();
This stops during the first frame. I have a callback function requestAnimFrame(animloop);
in the chopElement
function.
Also, is there a more thorough guide to using this API?
requestAnimationFrame() is 1 shot. You should call this method whenever you're ready to update your animation onscreen. This will request that your animation function be called before the browser performs the next repaint.
The requestAnimationFrame method returns an integer ID which can be used to cancel the queued request using the cancelAnimationFrame(id) method. The animation callback function can also accept a timestamp value, which is the time elapsed in milliseconds since the web page was loaded.
The requestAnimationFrame() API provides an efficient way to make animations in JavaScript. The callback function of the method is called by the browser before the next repaint on each frame.
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 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 puts a semicolon behind your return
statement. It does this because it is followed by a newline and the next line is a valid expression. In 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 undefined
and never executes the code behind the return statement. So window.requestAnimFrame
is undefined
. When you call it in animloop
, the javascript produces an error and stops execution. You can solve the problem by enclosing the expression in parentheses.
May I recommend the Chrome developer tools or firebug to inspect javascript execution. With these tools you would have seen the error. You should go about debugging it as follows (I'm assuming Chrome):
Uncaught TypeError: Property 'requestAnimFrame' of object [object DOMWindow] is not a function
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.Also, watch this video for some good practices in writing javascript, He also mentions the evil automatic semicolon insertion.
/* 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 illustrates clearly what I mean;
http://jsfiddle.net/XQpzU/4358/light/
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With