Skip to content

Instantly share code, notes, and snippets.

@gtzilla gtzilla/animator.js
Created Jul 30, 2011

Embed
What would you like to do?
/*
*
*
* file: animator.js
* author: gregory tomlinson
* desc: handy scaffolding for doing continous animations
*
* the requestion animation frame works very well as a lazy timer
* it's cpu cycles are low and it informs the browser the
* intention is to change the DOM
*
*
* usage:
* var animantion=animator();
* // where aF is current instance of animator();
* animation.add( function(data, ts, aF) {
* console.log(data.foo, ts);
* }, { foo: "bar" }, this);
*
*
* animation.add(function(data,ts,aF) {
* console.log(data.foo, ts);
* }, { foo: "car" }, this);
*
*
* // start it up
* animation.play();
*
*
* // full stop, ensign
* animation.stop();
*
*
* Addtional Declartion Styles / Type / Methods:
*
*
* animator(func, {}, this).play();
*
*
* animator({
* method:func,
* data:{},
* scope:this
* }).play();
*
*
* Provide a list of methods, format
* [{ method:func, data:{}, scope:this }]
*
* animator([{
* method:function(data,ts) {
* },
* data:{
* foo:"bar"
* },
* scope:this
* },{
* method:function(data,ts) {
* },
* data:{
* count:0
* },
* scope:this
* }]).play();
*
*
* */
(function(window){
var aF=function( methods_lst, data, scope ) {
this.actions=[];
this.init( methods_lst, data, scope );
return this;
}, animation_frame;
aF.prototype={
actions:[],
allowRun:true,
active:false,
add:function(method, data, scope ) {
this.actions.push({
"method":method,
"data":data,
"scope":scope || this
});
return this;
},
remove: function( method ) {
var actions=this.actions, item;
for(var i=0, l=actions.length; i<l; i++) {
item=actions[i];
if(item.method === method) {
actions.splice(i,1);
}
}
return this;
},
removeAll: function() {
this.actions=[];
},
play: function() {
if(this.active) {
return;
}
this.allowRun=true;
this.active=true;
this.run();
return this;
},
stop: function() {
this.allowRun=false;
return this;
},
run:function() {
var self=this;
if(!this.allowRun) {
this.active=false;
return this;
}
animation_frame(function(ts){
var result = self.runSequence(ts);
if(!result) {
self.active=false;
return;
}
self.run(); // continue the loop
});
return this;
},
/*
*
* This method is an exception, doesn't return 'this'
*
* Run Sequence can control animation on/off
*
* If any methods return not true (normal funcs return null aka not true)
* Loop will continue.
*
* To say that again, only one method called in run requence needs to
* return false to contine executing loop
*
* */
runSequence:function(ts) {
var actions=this.actions, item,
results=[], response;
for(var i=0, l=actions.length; i<l; i++) {
item=actions[i];
response=item.method.call( item.scope, item.data||{}, ts, this );
if(!response) {
results.push(i);
}
}
if(results.length > 0) {
return true;
}
return false;
},
init: function( methods_lst, data, scope ) {
var item;
if(methods_lst && typeof methods_lst === "function") {
this.add( methods_lst, data, scope );
} else if(methods_lst && methods_lst.length > 0 ) {
for(var i=0, l=methods_lst.length; i<l; i++) {
item=methods_lst[i];
this.add( item.method, item.data, item.scope );
}
} else if(methods_lst && methods_lst.method) {
this.add(methods_lst.method, methods_lst.data, methods_lst.scope );
}
return this;
}
}
function set_animation() {
animation_frame=(function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback){
setTimeout(function() {
callback(new Date().getTime());
}, 1000 / 60);
};
})();
}
set_animation();
window.animator=function( methods_lst, data, scope ) {
return new aF( methods_lst, data, scope );
}
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.