Skip to content

Instantly share code, notes, and snippets.

@jeef3
Created December 22, 2011 22:48
Show Gist options
  • Save jeef3/1512196 to your computer and use it in GitHub Desktop.
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.
(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;
};
}
})();
@jeef3
Copy link
Author

jeef3 commented Dec 22, 2011

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment