Created
December 22, 2011 22:48
-
-
Save jeef3/1512196 to your computer and use it in GitHub Desktop.
A small Javascript helper for continuous animations. This is to replace any time you've added a recursive setTimeout to create continuous animations.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
var ONE_FRAME_TIME = 1000.0 / 60.0; | |
Loopy = (function () { | |
var _loopy; | |
function Loopy() { | |
this.startTime = 0; | |
this.stepGroups = []; | |
_loopy = this; | |
} | |
Loopy.prototype.start = function (loop, canvas) { | |
if (typeof loop !== "function") return; | |
canvas = canvas || window; | |
this.startTime = new Date().getTime(); | |
var recursiveAnim, | |
animFrame = window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
window.oRequestAnimationFrame || | |
window.msRequestAnimationFrame || | |
null; | |
// Try to use a built in animation frame request, otherwise we fall back to a recursive setTimeout | |
if (animFrame !== null) { | |
if (window.mozRequestAnimationFrame) { | |
recursiveAnim = function () { | |
loop.call(canvas, _loopy.elapsed()); | |
animFrame(); | |
}; | |
window.addEventListener("MozBeforePaint", recursiveAnim, false); | |
animFrame(); | |
} else { | |
recursiveAnim = function () { | |
loop.call(canvas, _loopy.elapsed()); | |
animFrame(recursiveAnim, canvas); | |
}; | |
animFrame(recursiveAnim, canvas); | |
} | |
} else { | |
recursiveAnim = function () { | |
loop.call(canvas, _loopy.elapsed()); | |
setTimeout(recursiveAnim, ONE_FRAME_TIME); | |
}; | |
recursiveAnim(); | |
} | |
}; | |
Loopy.prototype.elapsed = function () { | |
return new Date().getTime() - this.startTime; | |
}; | |
Loopy.prototype.step = function (group, speed, elapsed) { | |
elapsed = elapsed || this.elapsed(); | |
var stepGroup = this.stepGroups[group] || | |
(this.stepGroups[group] = { lastStep: elapsed }), | |
lastStep = stepGroup.lastStep, | |
step = (elapsed - lastStep) / speed; | |
if (step < 0) { | |
// Since this is executed so often, only return a result if it's greater than 1 | |
return 0; | |
} else { | |
stepGroup.lastStep = elapsed; | |
return step; | |
} | |
}; | |
return new Loopy(); | |
})(); | |
// jQuery plugin | |
if (window.jQuery) { | |
jQuery.loopy = function (method) { | |
return Loopy[method].apply(Loopy, Array.prototype.slice.call(arguments, 1)); | |
}; | |
jQuery.fn.loopy = function (loop) { | |
Loopy.start(loop, this[0]); | |
return this; | |
}; | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
First, create a single run loop function:
var run = function (elapsed) {
// Place run loop code here
};
All animation should happen inside this function. The function will be passed an elapsed time in milliseconds from the start of execution. You can use this value to calculate how far things have moved. Or you can use the helper method.
Javascript
Loopy.start(run);
jQuery
$("#container").loopy(run);
or, without a canvas
$.loopy("start", run);
Step Helper
You can use the step helper to help you calculate how far your item needs to be moved:
Loopy.step(group, speed);
Where group is the name of an item group and speed is the speed the item is moving in speed number of milliseconds to travel one "unit". A single "unit" can be any measure you want, it's all relative. Example:
var myImages = $("#images");
var run = function () {
var step = $.loopy("step", "images", 400);
myImages.css({ left: "-=" + (step * 10) });
};
myImages.loopy(run);
This describes one "unit" as being 10 pixels, and that the images will move at a speed of 10 pixels every 400 milliseconds.