Wiedergabesteuerung für Webanimationen in Chrome 39

Anfang des Jahres wurde in Chrome 36 die Methode „element.animate“ als Teil der umfassenderen Web Animations-Spezifikation eingeführt. So sind effiziente, native Animationen möglich, die imperativ geschrieben werden. Entwickler haben dann die Möglichkeit, ihre Animationen und Übergänge mit dem für sie am besten geeigneten Ansatz zu erstellen.

Zur Wiederholung: So können Sie eine Wolke über den Bildschirm animieren und einen Rückruf ausführen, wenn die Animation abgeschlossen ist:

var player = cloud.animate([
    {transform: 'translateX(' + start + 'px)'},
    {transform: 'translateX(' + end + 'px)'}
], 5000);
player.onfinish = function() {
    console.info('Cloud moved across the screen!');
    startRaining(cloud);
};

Das ist unglaublich einfach und sollte unbedingt in Ihrem Werkzeugkasten enthalten sein, wenn Sie Animationen oder Übergänge erstellen. In Chrome 39 wurden dem von element.animate zurückgegebenen AnimationPlayer-Objekt jedoch Funktionen zur Wiedergabesteuerung hinzugefügt. Bisher konnten Sie nach dem Erstellen einer Animation nur cancel() aufrufen oder auf das Ereignis „Fertigstellen“ warten.

Diese Ergänzungen zur Wiedergabe eröffnen mit Webanimationen neue Möglichkeiten: Animationen lassen sich in ein universelles Tool umwandeln, anstatt die Übergänge vorschreiben zu müssen. „fixierte“ oder vordefinierte Animationen

Wiedergabe pausieren, zurückspulen oder Wiedergabegeschwindigkeit ändern

Aktualisieren wir zuerst das Beispiel oben, damit die Animation pausiert wird, wenn auf die Wolke geklickt wird:

cloud.addEventListener('mousedown', function() {
    player.pause();
});

Sie können auch das Attribut playbackRate ändern:

function changeWindSpeed() {
    player.playbackRate *= (Math.random() * 2.0);
}

Sie können auch die Methode reverse() aufrufen. Das entspricht normalerweise dem Invertieren des aktuellen playbackRate (Multiplikation mit −1). Es gibt jedoch einige Sonderfälle:

  • Wenn die durch die reverse()-Methode verursachte Änderung dazu führt, dass die laufende Animation effektiv beendet wird, wird auch die currentTime umgekehrt.Wenn beispielsweise eine brandneue Animation rückwärts abgespielt wird, wird die gesamte Animation rückwärts abgespielt.

  • Wenn der Player pausiert ist, wird die Animation abgespielt.

Scrubbing im Player

Ein AnimationPlayer ermöglicht jetzt das Ändern seines currentTime, während eine Animation ausgeführt wird. Normalerweise steigt dieser Wert mit der Zeit an (oder sinkt, wenn playbackRate negativ ist). So kann die Position einer Animation extern gesteuert werden, z. B. durch eine Nutzerinteraktion. Dies wird allgemein als Scrubbing bezeichnet.

Wenn Ihre HTML-Seite beispielsweise den Himmel darstellt und Sie die Position einer gerade abgespielten Wolke per Drag-and-drop ändern möchten, können Sie dem Dokument einige Handler hinzufügen:

var startEvent, startEventTime;
document.addEventListener('touchstart', function(event) {
    startEvent = event;
    startEventTime = players.currentTime;
    player.pause();
});
document.addEventListener('touchmove', function(event) {
    if (!startEvent) return;
    var delta = startEvent.touches[0].screenX -
        event.changedTouches[0].screenX;
    player.currentTime = startEventTime + delta;
});

Wenn Sie den Mauszeiger über das Dokument ziehen, ändert sich das currentTime, um die Entfernung vom ursprünglichen Ereignis widerzuspiegeln. Sie können die Animation auch fortsetzen, wenn die Geste endet:

document.addEventListener('touchend', function(event) {
    startEvent = null;
    player.play();
});

Dies kann sogar mit einem Rückwärtsverhalten kombiniert werden, je nachdem, wo die Maus auf der Seite aufgehoben wurde (kombinierte Demo).

Anstatt eine AnimationPlayer als Reaktion auf eine Nutzerinteraktion zu überspringen, kann ihre currentTime auch verwendet werden, um den Fortschritt oder Status anzuzeigen, z. B. den Status eines Downloads.

Der Vorteil dabei ist, dass mit AnimationPlayer ein Wert festgelegt werden kann und die zugrunde liegende native Implementierung die Fortschrittsvisualisierung übernimmt. Im Fall eines Downloads kann die Dauer einer Animation auf die Gesamtgröße des Downloads und currentTime auf die aktuell heruntergeladene Größe festgelegt werden (Demo).

UI-Übergänge und -Gesten

Mobile Plattformen sind schon seit Langem der Bereich gängiger Gesten wie Ziehen, Schieben, Ziehen und Ähnliches. Diese Touch-Gesten haben in der Regel ein gemeinsames Thema: eine verschiebbare UI-Komponente, z. B. „Zum Aktualisieren ziehen“ in einer Listenansicht oder eine Seitenleiste, die von der linken Seite des Bildschirms ausgezogen wird.

Mit Webanimationen lässt sich ein ähnlicher Effekt ganz einfach im Web reproduzieren – auf dem Computer oder auf Mobilgeräten. Wenn beispielsweise eine Geste zur Steuerung von currentTime abgeschlossen ist:

var steps = [ /* animation steps */ ];
var duration = 1000;
var player = target.animate(steps, duration);
player.pause();
configureStartMoveListeners(player);

var setpoints = [0, 500, 1000];
document.addEventListener('touchend', function(event) {
    var srcTime = player.currentTime;
    var dstTime = findNearest(setpoints, srcTime);
    var driftDuration = dstTime - srcTime;

    if (!driftDuration) {
    runCallback(dstTime);
    return;
    }

    var driftPlayer = target.animate(steps, {
    duration: duration,
    iterationStart: Math.min(srcTime, dstTime) / duration,
    iterations: Math.abs(driftDuration) / duration,
    playbackRate: Math.sign(driftDuration)
    });
    driftPlayer.onfinish = function() { runCallback(dstTime); };
    player.currentTime = dstTime;
});

Dadurch wird eine zusätzliche Animation erstellt, die einen „Drift“ ausführt. Diese Wiedergabe beginnt, während die Geste ausgeführt wurde, bis zum bekannten Ziel.

Das funktioniert, weil Animationen eine Priorität haben, die auf ihrer Erstellungsreihenfolge basiert: In diesem Fall hat driftPlayer Vorrang vor „player“. Wenn driftPlayer abgeschlossen ist, verschwinden driftPlayer und seine Auswirkungen. Die letzte Zeit stimmt jedoch mit der "currentTime" des zugrunde liegenden Spielers überein, sodass deine Benutzeroberfläche einheitlich bleibt.

Wenn Sie Katzenfreunde sind, gibt es eine Demo-Webanwendung, in der diese Gesten gezeigt werden. Die Website ist für Mobilgeräte optimiert und verwendet die Polyfill-Technologie für die Abwärtskompatibilität. Laden Sie sie also auf Ihrem Mobilgerät.

Jetzt loslegen und element.animate

Die element.animate-Methode ist aktuell total angesagt – egal, ob du sie für einfache Animationen verwendest oder die zurückgegebene AnimationPlayer auf andere Weise nutzt.

Diese beiden Funktionen werden auch in anderen modernen Browsern über eine leichte Polyfill-Funktion vollständig unterstützt. Diese Polyfill führt auch eine Funktionserkennung durch. Wenn Browseranbieter die Spezifikation implementieren, wird diese Funktion mit der Zeit immer schneller und besser.

Die Web Animations-Spezifikation wird sich ebenfalls weiterentwickeln. Wenn Sie die anstehenden Funktionen ausprobieren möchten, sind sie jetzt auch in einer detaillierteren Polyfill-Version verfügbar: web-animations-next.