Skip to content

Instantly share code, notes, and snippets.

@csuwildcat
Created January 24, 2010 20:17
Show Gist options
  • Save csuwildcat/285425 to your computer and use it in GitHub Desktop.
Save csuwildcat/285425 to your computer and use it in GitHub Desktop.
Fx.Flux
/*
---
script: Fx.Flux.js
description: Defines Fx.Flux, class that allows all available Fx options to be set per-property (duration, transition, events etc.)
license: MIT-style
authors:
- Daniel Buchner
requires:
- core:1.2.4/Fx.Morph
provides: [Fx.Flux]
...
*/
Fx.Flux = new Class({
Implements: [Events, Options],
Binds:['set', 'start', 'pause', 'resume', 'toggle', 'cancel', 'onComplete', 'chain', 'callChain'],
options: {
/*
onStart: $empty,
onCancel: $empty,
onComplete: $empty,
*/
fps: 50,
unit: false,
duration: 500,
link: 'ignore'
},
initialize: function(element, options){
this.element = document.id(element).store('flux', this);
this.setOptions(options);
this.fx = new Fx.Morph(this.element, options);
this.fx.chain = this.chain.bind(this);
this.fx.callChain = this.callChain.bind(this);
this.fx.onComplete = this.onComplete.bind(this);
this.reset = this.options;
this.cycle = [];
},
set: function(properties){
this.fx.set(properties);
return this.fx;
},
start: function(properties){
var duration = this.reset.duration;
var state = null;
for (var p in properties){
var splatter = $splat(properties[p]);
var options = null;
splatter.each(function(e, i, a){
if($type(e) == 'object'){
options = e;
duration = (e.duration > duration) ? e.duration : duration;
splatter.erase(e);
}
}, this);
var props = {};
props[p] = splatter;
if(p == 'visibility') state = props[p][0];
var merged = (options) ? $merge(this.reset, options) : this.reset;
var cachedFx = this.element.retrieve('flux:' + p);
if(cachedFx){
cachedFx.options = merged;
this.cycle.push(cachedFx);
cachedFx.start(props);
}
else{
var propFx = new Fx.Morph(this.element, merged);
this.cycle.push(propFx);
this.element.store('flux:' + p, propFx.start(props));
}
}
this.fx.options.duration = duration;
state = (state) ? state : this.element.getStyle('visibility');
this.fx.start({'visibility': state});
return this;
},
pause: function(){
this.cycle.each(function(e){ e.stopTimer() });
this.fx.stopTimer();
return this;
},
resume: function(){
this.cycle.each(function(e){ e.startTimer() });
this.fx.startTimer();
return this;
},
toggle: function(){
(this.fx.time < this.fx.options.duration) ? this.resume() : this.pause();
},
cancel: function(){
this.fx.cancel();
this.cycle.each(function(e){ e.cancel(); });
this.cycle.empty();
return this;
},
onComplete: function(){
this.cycle.empty();
this.fx.fireEvent('complete', this.fx.subject);
(this.fx.$chain.length) ? this.fx.callChain() : this.fx.fireEvent('chainComplete', this.fx.subject);
},
chain: function(fn, bind){
this.fx.$chain.extend([fn.bind(bind || this)]);
return this;
},
callChain: function(){
return (this.fx.$chain.length) ? this.fx.$chain.shift().run(arguments) : false;
}
});
Element.Properties.flux = {
set: function(options){
var flux = this.retrieve('flux');
if (flux) flux.cancel();
return this.eliminate('flux').store('flux:options', $extend({link: 'cancel'}, options));
},
get: function(options){
if (options || !this.retrieve('flux')){
if (options || !this.retrieve('flux:options')) this.set('flux', options);
this.store('flux', new Fx.Flux(this, this.retrieve('flux:options')));
}
return this.retrieve('flux');
}
};
Element.implement({
flux: function(props){
this.get('flux').start(props);
return this;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment