Skip to content

Instantly share code, notes, and snippets.

@hapticdata
Created March 29, 2012 15:50
Show Gist options
  • Save hapticdata/2238838 to your computer and use it in GitHub Desktop.
Save hapticdata/2238838 to your computer and use it in GitHub Desktop.
simplified animation using requestAnimationFrame with onComplete, stop and resume
/**
* animator factory for creating requestAnimationFrame callbacks
* and simplifying their cancellation. Includes Erik Moller polyfill
* @author Kyle Phillips
* @example
* animator(function(){
* //do this every time
* if(Math.random() > 0.9){
* this.complete();
* }
* }).onComplete(function(){
console.log("animation completed");
* }});
*/
var animator;
/**
* Polyfill for requestAnimationFrame and cancelAnimationFrame
* http://paulirish.com/2011/requestanimationframe-for-smart-animating/
*/
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
/**
* Main functionality,
* _Animator is inside closure, not publicly available, use animator()
*/
(function(){
var _Animator = function(){
this.__onCompleteCallbacks = [];
this.__onStopCallbacks = [];
this.__animating = false;
this.__complete = false;
};
_Animator.prototype = {
animate: function(callback){
//dont let it double-up
if(this.__animating){
return this;
}
if(this.__onStep === undefined && callback === undefined){
console.warn("animator received no function, cancelled");
}
if(callback !== undefined){
this.__onStep = callback;
}
this.__animating = true;
var self = this;
var drawFrame = function(){
self.__onStep.apply(self);
if(self.__animating){
self.request = requestAnimationFrame(drawFrame);
} else {
cancelAnimationFrame(self.request);
}
};
drawFrame();
return this;
},
complete: function(){
this.__animating = false;
this.__complete = true;
this.stop();
for(var i=0, len = this.__onCompleteCallbacks.length; i< len; i++){
this.__onCompleteCallbacks[i].apply( this );
}
return this;
},
onComplete: function(fn){
if(!fn)return;
this.__onCompleteCallbacks.push( fn );
return this;
},
onStop: function(fn){
if(!fn)return;
this.__onStopCallbacks.push( fn );
return this;
},
resume: function(){
this.animate();
return this;
},
stop: function(){
this.__animating = false;
for(var i=0, len = this.__onStopCallbacks.length; i< len; i++){
this.__onStopCallbacks[i].apply( this );
}
return this;
}
};
animator = function( fn ){
//if only one param was sent it should be the function
var _instance = new _Animator();
return _instance.animate(fn);
};
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment