Alle Timer in JavaScript basieren auf der JavaScript-Funktion der alten Schule setInterval()
o setTimeout()
. Auch jQuery verwendet dies intern.
Der Trick bei der Synchronisierung von Timern besteht darin, sicherzustellen, dass es nur einen setInterval()
aufgerufen wird, also bauen Sie selbst etwas.
Eine Animation kann mit gestaltet werden:
Jedes Mal, wenn Ihre Funktion nun von setInterval()
können Sie alle DOM-Elemente auf einmal an die richtige Position setzen. Um herauszufinden, wo sich ein Element bei jedem Animationsframe befinden sollte, verwenden Sie die Funktion:
var diff = ( to - from );
var stepValue = from + diff * percentage;
Die jQuery-Easing-Funktionen können direkt aufgerufen werden, und die letzte Anweisung wird:
var stepValue = jQuery.easing[ easingMethod ]( percentage, 0, from, diff );
Ich habe daraus einen Kurs gemacht:
/**
* Animation timeline, with a callback.
*/
function AnimationTimeline( params, onstep )
{
// Copy values.
// Required:
this.from = params.from || 0; // e.g. 0%
this.to = params.to || 1; // e.g. 100%
this.onstep = onstep || params.onstep; // pass the callback.
// Optional
this.steps = params.steps || 10;
this.duration = params.duration || 300;
this.easing = params.easing || "linear";
// Internal
this._diff = 0;
this._step = 1;
this._timer = 0;
}
jQuery.extend( AnimationTimeline.prototype, {
start: function()
{
if( this.from == this.to )
return;
if( this._timer > 0 )
{
self.console && console.error("DOUBLE START!");
return;
}
var myself = this;
this._diff = ( this.to - this.from );
this._timer = setInterval( function() { myself.doStep() }, this.duration / this.steps );
}
, stop: function()
{
clearInterval( this._timer );
this._timer = -1;
this._queue = [];
}
, doStep: function()
{
// jQuery version of: stepValue = from + diff * percentage;
var percentage = ( this._step / this.steps );
var stepValue = jQuery.easing[ this.easing ]( percentage, 0, this.from, this._diff );
// Next step
var props = { animationId: this._timer + 10
, percentage: percentage
, from: this.from, to: this.to
, step: this._step, steps: this.steps
};
if( ++this._step > this.steps )
{
stepValue = this.to; // avoid rounding errors.
this.stop();
}
// Callback
if( this.onstep( stepValue, props ) === false ) {
this.stop();
}
}
});
Und jetzt können Sie es benutzen:
var el1 = $("#element1");
var el2 = $("#element2");
var animation = new AnimationTimeline( {
easing: "swing"
, onstep: function( stepValue, animprops )
{
// This is called for every animation frame. Set the elements:
el1.css( { left: ..., top: ... } );
el2.css( { left: ..., top: ... } );
}
});
// And start it.
animation.start();
Das Hinzufügen einer Pause/eines Resümees ist eine Übung für den Leser.