Web Animations API-Verbesserungen in Chromium 84

Animationen mit Promises orchestrieren, Leistung mit austauschbaren Animationen verbessern, flüssigere Animationen mit Composite-Modi erzielen und vieles mehr.

Veröffentlicht: 27. Mai 2020

Wenn sie richtig eingesetzt werden, verbessern Animationen die Wahrnehmung und das Erinnerungsvermögen der Nutzer in Bezug auf Ihre Marke, leiten Nutzeraktionen und helfen Nutzern, sich in Ihrer Anwendung zurechtzufinden. Sie bieten Kontext in einem digitalen Raum.

Die Web Animations API ist ein Tool, mit dem Entwickler imperative Animationen mit JavaScript schreiben können. Sie wurde geschrieben, um sowohl CSS-Animationen als auch Übergänge zu unterstützen und die Entwicklung zukünftiger Effekte sowie die Komposition und das Timing bestehender Effekte zu ermöglichen.

Während Firefox und Safari bereits alle Funktionen der Spezifikation implementiert haben, bietet Chromium 84 eine Reihe von bisher nicht unterstützten Funktionen für Chrome und Edge, die die browserübergreifende Interoperabilität ermöglichen.

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

Erste Schritte

Wenn Sie bereits @keyframe-Regeln verwendet haben, sollte Ihnen das Erstellen einer Animation mit der Web Animations API sehr vertraut vorkommen. Zuerst müssen Sie ein Keyframe-Objekt erstellen. Was im CSS so aussehen könnte:

@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 Parameter für Animationen in CSS fest:

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

So würden Sie den Wert in JavaScript festlegen:

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

Die Menge an Code ist ungefähr gleich, aber mit JavaScript haben Sie einige zusätzliche Möglichkeiten, die Sie mit CSS allein nicht haben. Dazu gehört die Möglichkeit, Effekte in einer bestimmten Reihenfolge abzuspielen, und eine bessere Kontrolle über die Wiedergabestatus.

Über element.animate() hinaus

Mit dem 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 für ein Element zurückgibt, unabhängig davon, ob sie mit element.animate() oder mit CSS-Regeln (CSS-Animation oder ‑Übergang) erstellt wurden. Hier ein Beispiel:

Zuerst "get" Sie die Keyframes für den Übergang, um zu bestimmen, von wo aus der Übergang erfolgt. Anschließend erstellen Sie zwei neue Deckkraftanimationen, um den Überblendungseffekt zu ermöglichen. Nachdem die Überblendung abgeschlossen ist, löschen Sie die Kopie.

Animationen mit Promises koordinieren

In Chromium 84 stehen jetzt zwei Methoden zur Verfügung, die mit Promises verwendet werden können: animation.ready und animation.finished.

  • Mit animation.ready kannst du warten, bis ausstehende Änderungen wirksam werden, z. B. beim Wechseln zwischen Wiedergabesteuerungsmethoden wie „Wiedergabe“ und „Pause“.
  • Mit animation.finished kann benutzerdefinierter JavaScript-Code ausgeführt werden, wenn eine Animation abgeschlossen ist.

Wir setzen unser Beispiel fort und erstellen mit animation.finished eine orchestrierte Animationskette. Hier sehen Sie eine vertikale Transformation (scaleY), gefolgt von einer horizontalen Transformation (scaleX) und einer Änderung der Deckkraft eines untergeordneten Elements:

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 wir den nächsten Animationssatz in der Kette ausgeführt haben. So werden die Animationen in der richtigen Reihenfolge angezeigt und Sie können sogar Effekte auf verschiedene Zielelemente mit unterschiedlichen Optionen anwenden (z. B. Geschwindigkeit und Easing).

In CSS wäre es mühsam, dies nachzubilden, insbesondere wenn Sie mehreren Elementen eindeutige, aber sequenzierte Animationen zuweisen möchten. Sie müssten ein @keyframe verwenden, die richtigen Timing-Prozentsätze für die Animationen festlegen und animation-delay verwenden, bevor die Animationen in der Sequenz ausgelöst werden.

Beispiel: Wiedergabe, Pause und Rückwärts

Was sich öffnen lässt, sollte sich auch schließen lassen. Glücklicherweise bietet die Web Animations API seit Chromium 39 die Möglichkeit, Animationen abzuspielen, zu pausieren und umzukehren.

Mit .reverse() können Sie die zuvor gezeigte Animation umkehren, wenn Sie noch einmal auf die Schaltfläche klicken. So können Sie eine reibungslosere und kontextbezogenere Interaktion für unser Modal erstellen.

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

Sie können zwei Animationen erstellen, die auf die Wiedergabe warten (openModal und eine Inline-Deckkrafttransformation), und dann eine der Animationen pausieren, um sie zu verzögern, bis die andere abgeschlossen ist. Anschließend können Sie Promises verwenden, um zu warten, bis die einzelnen Vorgänge abgeschlossen sind, bevor Sie sie abspielen. Schließlich können Sie prüfen, ob ein Flag gesetzt ist, und dann jede Animation umkehren.

Beispiel: Dynamische Interaktionen mit Teil-Keyframes

Retargeting-Beispiel, bei dem die Animation durch einen Mausklick an einen neuen Ort angepasst wird. Demo auf CodePen ansehen
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

In diesem Beispiel gibt es nur einen Keyframe und keine angegebene Startposition. Dies ist ein Beispiel für die Verwendung von Teil-Keyframes. Der Maus-Handler führt hier einige Aktionen aus: Er legt einen neuen Endpunkt fest und löst eine neue Animation aus. Die neue Startposition wird aus 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.

Leistungssteigerung durch austauschbare Animationen

Wenn Sie Animationen auf Grundlage von Ereignissen erstellen, z. B. bei 'mousemove', wird jedes Mal eine neue Animation erstellt. Das kann schnell zu Speicherproblemen und Leistungseinbußen führen. Um dieses Problem zu beheben, wurden in Chromium 83 ersetzbare Animationen eingeführt. Dadurch ist eine automatische Bereinigung möglich, bei der abgeschlossene Animationen als ersetzbar gekennzeichnet und automatisch entfernt werden, wenn sie durch eine andere abgeschlossene Animation ersetzt werden. Dazu ein Beispiel:

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

Jedes Mal, wenn sich die Maus bewegt, berechnet der Browser die Position für jede Kugel in der Kometenschweif neu und erstellt eine Animation für diesen neuen Punkt. Der Browser weiß jetzt, dass alte Animationen entfernt werden müssen (um sie zu ersetzen), wenn:

  1. Die Animation ist abgeschlossen.
  2. Es gibt eine oder mehrere Animationen, die in der Composite-Reihenfolge höher stehen und 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. Verwenden Sie dazu anim.onremove, um den Zähler auszulösen.

Es gibt einige zusätzliche Attribute und Methoden, mit denen Sie die Animation noch besser steuern können:

  • Mit animation.replaceState lässt sich nachverfolgen, ob eine Animation aktiv, beibehalten oder entfernt wird.
  • animation.commitStyles() aktualisiert den Stil eines Elements basierend auf dem zugrunde liegenden Stil sowie allen Animationen des Elements in der zusammengesetzten Reihenfolge.
  • animation.persist() kennzeichnet eine Animation als nicht austauschbar.

Flüssigere Animationen mit Composite-Modi

Mit der Web Animations API können Sie jetzt den Composite-Modus Ihrer Animationen festlegen. Neben dem Standardmodus „replace“ sind auch die Modi „additive“ und „accumulative“ möglich. Mit Zusammengesetzten Modi können Entwickler separate Animationen schreiben und steuern, wie Effekte kombiniert werden. Es werden jetzt drei Kompositionsmodi unterstützt: 'replace' (Standardmodus), 'add' und 'accumulate'.

Beim Compositing von Animationen kann ein Entwickler kurze, unterschiedliche Effekte schreiben und sehen, wie sie kombiniert werden. Im folgenden Beispiel wenden wir auf jedes Rechteck einen Keyframe für Drehung und Skalierung an. Die einzige Anpassung ist der als Option hinzugefügte Compositing-Modus:

Eine Demo mit den Standard-, Add- und Accumulate-Zusammensetzungsmodi. Demo auf CodePen ansehen

Im Standard-Zusammensetzungsmodus 'replace' wird die Eigenschaft „transform“ durch die endgültige Animation ersetzt und endet bei rotate(360deg) scale(1.4). Bei 'add' wird die Rotation hinzugefügt und die Skalierung multipliziert, was zu einem Endzustand von rotate(720deg) scale(1.96) führt. 'accumulate' kombiniert die Transformationen und führt zu rotate(720deg) scale(1.8). Weitere Informationen zu den Feinheiten dieser zusammengesetzten Modi finden Sie in der Web Animations-Spezifikation unter The CompositeOperation and CompositeOperationOrAuto enumerations.

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

Ein federndes Drop-down-Menü, auf das zwei zusammengesetzte Animationen angewendet wurden. Demo auf CodePen ansehen

Hier werden zwei top-Animationen zusammengesetzt. Die erste ist eine Makroanimation, bei der das Drop-down-Menü als Einblendung von oben über die gesamte Höhe des Menüs verschoben wird. Die zweite ist eine Mikroanimation, bei der das Menü beim Erreichen des unteren Rands leicht zurückfedert. Mit dem zusammengesetzten Modus 'add' wird ein sanfterer Übergang ermöglicht.

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' });
  });

Wie geht es mit der Web Animations API weiter?

Das sind alles spannende Neuerungen für Animationen in aktuellen Browsern. Weitere sind bereits in der Entwicklung. Weitere Informationen zu den nächsten Schritten finden Sie in den folgenden zukünftigen Spezifikationen: