gli eventi di Morph sono predefiniti in Fx (sono onStart, onComplete e onCancel e onChainComplete), se vuoi crearne di nuovi devi ridefinire la classe Fx.
Ne ho fatta una per implementare gli eventi onStep (ad ogni step dell'effetto), onPause (quando chiami pause) ed onResume (quando riprendi l'effetto):
Codice PHP:
var Fx = new Class({
Implements: [Chain, Events, Options],
options: {
/*
onStart: $empty,
onCancel: $empty,
onComplete: $empty,
onStep: $empty,
onPause: $empty,
onResume: $empty
*/
fps: 50,
unit: false,
duration: 500,
link: 'ignore'
},
initialize: function(options){
this.subject = this.subject || this;
this.setOptions(options);
this.options.duration = Fx.Durations[this.options.duration] || this.options.duration.toInt();
var wait = this.options.wait;
if (wait === false) this.options.link = 'cancel';
},
getTransition: function(){
return function(p){
return -(Math.cos(Math.PI * p) - 1) / 2;
};
},
step: function(){
var time = $time();
if (time < this.time + this.options.duration){
var delta = this.transition((time - this.time) / this.options.duration);
this.onStep(delta);
this.set(this.compute(this.from, this.to, delta));
} else {
this.onStep(1);
this.set(this.compute(this.from, this.to, 1));
this.complete();
}
},
set: function(now){
return now;
},
compute: function(from, to, delta){
return Fx.compute(from, to, delta);
},
check: function(){
if (!this.timer) return true;
switch (this.options.link){
case 'cancel': this.cancel(); return true;
case 'chain': this.chain(this.caller.bind(this, arguments)); return false;
}
return false;
},
start: function(from, to){
if (!this.check(from, to)) return this;
this.from = from;
this.to = to;
this.time = 0;
this.transition = this.getTransition();
this.startTimer();
this.onStart();
return this;
},
complete: function(){
if (this.stopTimer()) this.onComplete();
return this;
},
cancel: function(){
if (this.stopTimer()) this.onCancel();
return this;
},
onStart: function(){
this.fireEvent('start', this.subject);
},
onComplete: function(){
this.fireEvent('complete', this.subject);
if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
},
onCancel: function(){
this.fireEvent('cancel', this.subject).clearChain();
},
pause: function(){
if(this.stopTimer())this.onPause();
return this;
},
resume: function(){
this.onResume();
this.startTimer();
return this;
},
onPause: function(){
this.fireEvent('pause', this.subject);
},
onResume: function(){
this.fireEvent('resume', this.subject);
},
onStep: function(delta){
this.fireEvent('step', [this.subject, delta]);
},
stopTimer: function(){
if (!this.timer) return false;
this.time = $time() - this.time;
this.timer = $clear(this.timer);
return true;
},
startTimer: function(){
if (this.timer) return false;
this.time = $time() - this.time;
this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this);
return true;
}
});
Funziona sia su tween che morph allo stesso modo:
codice:
<script type="text/javascript" src="js/mootools-1.2.2-core-nc.js"></script>
<script type="text/javascript">
window.addEvent('load', function(){
(function(){mpr.pause()}).delay(50);
(function(){mpr.resume()}).delay(100);
var mpr = $('Space').get('morph', {
onStart : function(){
$('Logger').appendText("Space has started");
new Element('br').inject($('Logger'));
},
onComplete : function(){
$('Logger').appendText("Space has completed");
new Element('br').inject($('Logger'));
},
onStep : function(item, time){
$('Logger').appendText("Space has stepped % "+time*100);
new Element('br').inject($('Logger'));
},
onPause : function(){
$('Logger').appendText("Space has paused");
new Element('br').inject($('Logger'));
},
onResume : function(){
$('Logger').appendText("Space has resumed");
new Element('br').inject($('Logger'));
}
}).start({
'width' : 300
})
})
</script>
<div id="Space" style="width: 100px; height: 100px; background-color: #66ccff;">
</div>
<div id="Logger"></div>
N.B. stai attento che onStep è chiamato molte volte e se fai cose pesanti rischi di rallentare lo script, già il mio dura il doppio.