/* limitLoop.js - limit the frame-rate when using requestAnimation frame Released under an MIT license. Why use it? ---------------- A consistent frame-rate can be better than a janky experience only occasionally hitting 60fps. Use this trick to target a specific frame- rate (e.g 30fps, 48fps). This type of trick works better when you know you have a fixed amount of work to be done and it will always take longer than 16.6ms. It doesn't work as well when your workload is somewhat variable. Solution ---------------- When we draw, deduct the last frame's execution time from the current time to see if the time elapsed since the last frame is more than the fps-based interval or not. Should the condition evaluate to true, set the time for the current frame which will be the last frame execution time in the next drawing call. Prior art / inspiration ------------------------ http://cssdeck.com/labs/embed/gvxnxdrh/0/output http://codetheory.in/controlling-the-frame-rate-with-requestanimationframe/ */ // rAF window.requestAnimationFrame = function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function(f) { window.setTimeout(f,1e3/60); } }(); var limitLoop = function (fn, fps) { var then = new Date().getTime(); var oldtime = 0; // custom fps, otherwise fallback to 60 fps = fps || 60; return (function loop(time) { requestAnimationFrame(loop); var interval = 1000 / (this.fps || fps); var now = new Date().getTime(); var delta = now - then; if (delta > interval) { // Update time // now - (delta % interval) is an improvement over just // using then = now, which can end up lowering overall fps then = now - (delta % interval); // calculate fps var frames = 1000 / (time - oldtime) oldtime = time; // call the fn, passing current fps to it fn(frames); } }(0)); };