Web Animations API-Verbesserungen in Chromium 84

Animationen mit Versprechen orchestrieren, Leistungsverbesserungen mit austauschbaren Animationen, flüssigere Animationen mit Kompositmodi und vieles mehr.

Kevin Ellis
Kevin Ellis

Veröffentlicht: 27. Mai 2020

Bei richtiger Verwendung verbessern Animationen die Wahrnehmung und Erinnerung der Nutzer an Ihre Marke, leiten sie zu Nutzeraktionen und helfen ihnen, sich in Ihrer Anwendung zurechtzufinden. So schaffen sie Kontext in einem digitalen Raum.

Die Web Animations API ist ein Tool, mit dem Entwickler imperative Animationen mit JavaScript schreiben können. Er wurde entwickelt, um sowohl CSS-Animationen als auch -Übergänge zu unterstützen und zukünftige Effekte zu entwickeln sowie vorhandene Effekte zu komponieren und zu timen.

In Firefox und Safari sind bereits alle Funktionen der Spezifikation implementiert. Chromium 84 bietet jedoch eine Reihe zuvor nicht unterstützter Funktionen für Chrome und Edge, die die plattformübergreifende Interoperabilität ermöglichen.

Die Web Animations API wurde erstmals in Chromium-Version 36 im Juli 2014 eingeführt. Jetzt wird die Spezifikation in Version 84 vollständig sein, die im Juli 2020 eingeführt wird.
Die lange Geschichte der Web Animations API in Chromium.

Erste Schritte

Wenn Sie bereits @keyframe-Regeln verwendet haben, sollten Sie mit dem Erstellen einer Animation mit der Web Animations API vertraut sein. Zuerst müssen Sie ein Keyframe-Objekt erstellen. Im CSS könnte das so aussehen:

@keyframes openAnimation {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}

würde in JavaScript so aussehen:

const openAnimation = [
  { transform: 'scale(0)' },
  { transform: 'scale(1)' },
];

Hier legen Sie die Parameter für die Animation in CSS fest:

.modal {
  animation: openAnimation 1s 1 ease-in;
}

In JS würdest du Folgendes festlegen:

document.querySelector('.modal').animate(
    openAnimation, {
      duration: 1000, // 1s
      iterations: 1, // single iteration
      easing: 'ease-in' // easing function
    }
);

Die Codemenge ist ungefähr gleich, aber mit JavaScript haben Sie einige Superkräfte, die Sie mit CSS allein nicht haben. Dazu gehören die Möglichkeit, Effekte zu sequenzieren, und eine verbesserte Kontrolle über die Wiedergabestatus.

Mehr als element.animate()

Mit diesem Update ist die Web Animations API jedoch nicht mehr auf Animationen beschränkt, die mit element.animate() erstellt wurden. Wir können auch CSS-Animationen und ‑Übergänge bearbeiten.

getAnimations() ist eine Methode, die alle Animationen zu einem Element zurückgibt, unabhängig davon, ob es mit element.animate() oder mithilfe von CSS-Regeln (CSS-Animation oder -Übergang) erstellt wurde. Hier ist ein Beispiel:

Zuerst "get" Sie die keyframes für den Übergang, um festzulegen, von wo aus der Übergang erfolgt. Dann erstellen Sie zwei neue Deckkraftanimationen, die den Überblenden-Effekt aktivieren. Sobald die Überblendung abgeschlossen ist, löschen Sie die Kopie.

Animationen mit Versprechen orchestrieren

In Chromium 84 gibt es jetzt zwei Methoden, die mit Versprechen verwendet werden können: animation.ready und animation.finished.

  • animation.ready ermöglicht es, auf die Wirksamkeit ausstehender Änderungen zu warten (d. h. zwischen Wiedergabemethoden wie „Wiedergabe“ und „Pausieren“ zu wechseln).
  • Mit animation.finished können Sie benutzerdefinierten JavaScript-Code ausführen, wenn eine Animation abgeschlossen ist.

Fahren wir mit unserem Beispiel fort und erstellen eine orchestrierte Animationskette mit animation.finished. Hier sehen Sie eine vertikale Transformation (scaleY), eine horizontale Transformation (scaleX) und eine Deckkraftänderung für ein untergeordnetes Element:

Transformationen und Deckkraft auf ein sich öffnendes modales Element anwenden. Demo auf Codepen ansehen
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});

Wir haben diese Animationen mit animation.finished.then() verkettet, bevor der nächste Animationssatz in der Kette ausgeführt wurde. Auf diese Weise erscheinen die Animationen in der richtigen Reihenfolge und Sie wenden Effekte sogar auf verschiedene Zielelemente mit unterschiedlichen Optionen (z. B. Geschwindigkeit und Leichtigkeit) an.

In CSS wäre dies umständlich nachzubilden, insbesondere wenn eindeutige, aber dennoch sequenzierte Animationen auf mehrere Elemente angewendet werden. Sie müssten ein @keyframe verwenden, die richtigen Prozentsätze für das Timing sortieren, um die Animationen zu platzieren, und animation-delay verwenden, bevor die Animationen in der Sequenz ausgelöst werden.

Beispiel: Wiedergeben, Pausieren und Umkehren

Was sich öffnen lässt, sollte sich auch schließen lassen. Glücklicherweise können wir seit Chromium 39 mit der Web Animations API unsere Animationen abspielen, pausieren und rückwärts abspielen.

Sie können die zuvor gezeigte Animation mit .reverse() noch einmal anklicken, um eine flüssige, umgekehrte Animation zu erhalten. So können wir die Interaktion mit dem Modalfenster flüssiger und kontextbezogener gestalten.

Beispiel für ein modales Fenster, das sich durch Klicken auf eine Schaltfläche öffnet und schließt. Demo auf Glitch ansehen

Sie können zwei Animationen erstellen, die noch nicht wiedergegeben werden (openModal und eine Inline-Transparenztransformation), und dann eine der Animationen pausieren, bis die andere fertig ist. Mit Promis kannst du dann warten, bis ein Spiel beendet ist. Prüfen Sie abschließend, ob ein Flag gesetzt ist, und kehren Sie dann jede Animation um.

Beispiel: Dynamische Interaktionen mit teilweisen Frames

Beispiel für Retargeting, bei dem die Animation durch einen Mausklick an eine neue Position angepasst wird. Demo zu Glitch ansehen
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

In diesem Beispiel gibt es nur einen Keyframe und keine Startposition. Dies ist ein Beispiel für die Verwendung von teilweisen Frames. Der Maus-Handler führt hier einige Schritte aus: er legt eine neue Endposition fest und löst eine neue Animation aus. Die neue Startposition wird von der aktuellen zugrunde liegenden Position abgeleitet.

Neue Übergänge können ausgelöst werden, während bestehende noch laufen. Das bedeutet, dass der aktuelle Übergang unterbrochen und ein neuer erstellt wird.

Leistungsverbesserungen durch austauschbare Animationen

Wenn Sie auf Ereignissen basierende Animationen erstellen, z. B. auf 'mousemove', wird jedes Mal eine neue Animation erstellt. Das kann schnell viel Arbeitsspeicher verbrauchen und die Leistung beeinträchtigen. Um dieses Problem zu beheben, wurden in Chromium 83 austauschbare Animationen eingeführt. Dadurch ist eine automatische Bereinigung möglich, bei der fertige Animationen als austauschbar gekennzeichnet und automatisch entfernt werden, wenn sie durch eine andere fertige Animation ersetzt werden. Dazu ein Beispiel:

Eine Kometenspur wird animiert, wenn sich die Maus bewegt. Demo auf Glitch ansehen
elem.addEventListener('mousemove', evt => {
  rectangle.animate(
    { transform: translate(${evt.clientX}px, ${evt.clientY}px) },
    { duration: 500, fill: 'forwards' }
  );
});

Jedes Mal, wenn die Maus bewegt wird, berechnet der Browser die Position für jeden Ball im Kometenschweif neu und erstellt eine Animation zu diesem neuen Punkt. Der Browser weiß jetzt, dass alte Animationen in den folgenden Fällen entfernt werden müssen (ermöglicht ein Ersetzen), wenn Folgendes zutrifft:

  1. Die Animation ist beendet.
  2. Es gibt eine oder mehrere Animationen in der Zusammenstellung, die ebenfalls abgeschlossen sind.
  3. Bei den neuen Animationen werden dieselben Eigenschaften animiert.

Sie können genau sehen, wie viele Animationen ersetzt werden, indem Sie mit jeder entfernten Animation einen Zähler hochzählen und den Zähler mit anim.onremove auslösen.

Es gibt noch einige weitere Möglichkeiten, die Animation zu steuern:

  • Mit animation.replaceState() können Sie nachverfolgen, ob eine Animation aktiv, beibehalten oder entfernt wurde.
  • animation.commitStyles() aktualisiert den Stil eines Elements basierend auf dem zugrunde liegenden Stil zusammen mit allen Animationen für das Element in der zusammengesetzten Reihenfolge.
  • animation.persist() kennzeichnet eine Animation als nicht austauschbar.

Flüssigere Animationen mit zusammengesetzten Modi

Mit der Web Animations API können Sie jetzt den Kompositionsmodus Ihrer Animationen festlegen. Das bedeutet, dass sie zusätzlich zum Standardmodus „Ersetzen“ additiv oder kumulativ sein können. Mit zusammengesetzten Modi können Entwickler verschiedene Animationen schreiben und haben die Kontrolle darüber, wie Effekte kombiniert werden. Es werden jetzt drei zusammengesetzte Modi unterstützt: 'replace' (Standardmodus), 'add' und 'accumulate'.

Wenn Sie Animationen erstellen, kann ein Entwickler kurze, eindeutige Effekte schreiben und diese dann zusammen anzeigen lassen. Im folgenden Beispiel wird ein Rotations- und Skalierungs-Keyframe auf jedes Feld angewendet. Die einzige Anpassung ist der zusammengesetzte Modus, der als Option hinzugefügt wird:

Eine Demo, die die Standard-, Additions- und Aggregationsmodi zeigt. Demo zu Glitch ansehen

Im standardmäßigen 'replace'-Kompositmodus ersetzt die finale Animation die Transform-Eigenschaft und endet bei rotate(360deg) scale(1.4). Bei 'add' wird die Drehung addiert und die Skalierung multipliziert, was zu einem Endzustand von rotate(720deg) scale(1.96) führt. 'accumulate' kombiniert die Transformationen, was zu rotate(720deg) scale(1.8) führt. Weitere Informationen über die Komplexität dieser zusammengesetzten Modi finden Sie in den Enumerationen "CompositeOperation" und "CompositeOperationOrAuto" in der Spezifikation "Web Animations".

Sehen Sie sich das folgende Beispiel für ein UI-Element an:

Ein hüpfendes Drop-down-Menü, auf das zwei zusammengesetzte Animationen angewendet werden. Demo auf Glitch ansehen

Hier werden zwei top-Animationen zusammengesetzt. Die erste ist eine Makroanimation, bei der das Dropdown-Menü als Slide-in-Effekt vom oberen Rand der Seite um die volle Höhe des Menüs selbst verschoben wird. Bei der zweiten handelt es sich um eine Mikroanimation, die einen kleinen Sprung herbeiführt, wenn sie den unteren Rand erreicht. Mit dem 'add'-Kompositmodus können Sie einen flüssigeren Übergang erzielen.

const dropDown = menu.animate(
    [
      { top: `${-menuHeight}px`, easing: 'ease-in' },
      { top: 0 }
    ], { duration: 300, fill: 'forwards' });

  dropDown.finished.then(() => {
    const bounce = menu.animate(
      [
        { top: '0px', easing: 'ease-in' },
        { top: '10px', easing: 'ease-out' },
        { ... }
      ], { duration: 300, composite: 'add' });
  });

Die Zukunft der Web Animations API

Das sind spannende Ergänzungen zu den Animationsfunktionen in den heutigen Browsern. Weitere sind in Planung. Weitere Informationen zu den nächsten Schritten finden Sie in diesen zukünftigen Spezifikationen: