-
-
Save mrdoob/838785 to your computer and use it in GitHub Desktop.
/** | |
* Provides requestAnimationFrame in a cross browser way. | |
* @author paulirish / http://paulirish.com/ | |
*/ | |
if ( !window.requestAnimationFrame ) { | |
window.requestAnimationFrame = ( function() { | |
return window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
window.oRequestAnimationFrame || | |
window.msRequestAnimationFrame || | |
function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) { | |
window.setTimeout( callback, 1000 / 60 ); | |
}; | |
} )(); | |
} |
Now you know how it feels! (Google Axis ;D)
Now seriously, he didn't specify... he pasted the snippet on a issue:
https://github.com/mrdoob/three.js/issues/closed#issue/118
I'll change the credit ;)
Paul, is this the one that you wrote?
https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/sdk/demos/common/webgl-utils.js (end of the file)
Basically. Gregg Tavares had an uglier one there before and I rewrote it to what I just posted: http://paulirish.com/2011/requestanimationframe-for-smart-animating/
Then Gregg made it a proper polyfill with the full requestAnimationFrame
method (and dropped it into webgl-utils). I don't totally agree with that as the spec might potentially change. Haven't walked over and talked to him about it yet. :)
Should it not be setInverval
? I read that setTimeout
comes with extra unwanted delays (http://nokarma.org/2010/02/02/javascript-game-development-the-game-loop/).
paul: I see I see! :)
louisstow: If you have the setTimeout at the befinning of the loop you shouldn't get delays.
surely there should be something to sync animations - so they all occur in the same event loop ?
window.requestAnimFrame = (function() {
var fns = []
, timeout;
function run() {
while(fns.length) fns.shift()()
timeout = null
}
var self = this
// shim layer with setTimeout fallback
var onNextFrame = self.requestAnimationFrame ||
self.webkitRequestAnimationFrame ||
self.mozRequestAnimationFrame ||
self.oRequestAnimationFrame ||
self.msRequestAnimationFrame ||
function( callback ) {
self.setTimeout(callback, 1000 / 60);
};
return function(fn) {
fns.push(fn)
timeout = timeout || onNextFrame(run)
}
})();
How would you modify the latest jQuery with this shim and should I expect any performance improvements??
I believe this is the one line that sets up the animation timing
timerId = setInterval( fx.tick, fx.interval );
jquery 1.6.1 supported this:
if ( t() && jQuery.timers.push(t) && !timerId ) {
// Use requestAnimationFrame instead of setInterval if available
if ( requestAnimationFrame ) {
timerId = 1;
raf = function() {
// When timerId gets set to null at any point, this stops
if ( timerId ) {
requestAnimationFrame( raf );
fx.tick();
}
};
requestAnimationFrame( raf );
} else {
timerId = setInterval( fx.tick, fx.interval );
}
}
setTimeout is many times inaccurate, and so is setInterval. More importantly, however, setTimeout(1000/60) doesn't take into account where we are wrt to the next vsync (it always assume we have the full frame time ahead of us), so it needs to align to the "independent" intervals of an imaginary vsync signal.
var rAF = function(callback) {
var interval = 1000 / 60;
var now = (window.performance && window.performance.now) ?
window.performance.now() :
Date.now();
// setTimeout can return early, make sure to target the next frame.
if (this.lastTarget && now < this.lastTarget)
now = this.lastTarget + 0.01; // Floating point errors may result in just too early.
var delay = interval - now % interval;
this.lastTarget = now + delay;
setTimeout(callback, delay);
};
My animation is magically smooth now! ;)
just leaving there CoffeeScript code snippet
###
# Provides requestAnimationFrame in a cross browser way.
# @author paulirish / http://paulirish.com/
###
unless window.requestAnimationFrame
window.requestAnimationFrame = window.webkitRequestAnimationFrame or
window.mozRequestAnimationFrame or
window.oRequestAnimationFrame or
window.msRequestAnimationFrame or
(callback, element) -> window.setTimeout callback, 1000 / 60
hi, what is the diff to the following last post? http://codereview.stackexchange.com/questions/60216/gameloop-with-requestanimationframe (cc GameAlchemist answered Aug 19 '14 at 11:58)
I cant understand one thing, why do we need to use the delay as 1000/60
why not just the resulting figure that evaluates by dividing 1000
by 60
what if I just put any round figure, and does animationFrameRate
help us slowing down the animation without the setTimeout
function, and under what conditions should we use it this way setTimeout(callback, 1000 / 60);
and not setTimeout(callback, 1000);
Hi @mrdoob, why do we need the /* DOMElement Element */ element
in the function?
@buttflattery I know this is an old post, but I'm replying for any future people who see this. You use 1000 / 60
because it results to around 16.667
milliseconds. If you were to use this number, it would call the render function almost exactly 60 times per second, meaning 60 FPS. You could easily do 1000 / 80
to get 80 FPS if you really wanted, but 60 FPS is a common number for monitor refresh rates. If you were to use 1000
as the delay, then you would only get 1 frame per second.
hey i wrote that!
gregg stealing my glory. >:)