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 geschrieben, um sowohl CSS-Animations- als auch -Übergangsimplementierungen zu untermauern und die Entwicklung zukünftiger Effekte sowie die Erstellung und Abstimmung vorhandener Effekte zu ermöglichen.

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 traf Chromium erstmals in Version 36 im Juli 2014. Die Spezifikation wird in Version 84, die im Juli 2020 veröffentlicht wird, vollständig sein.
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 bessere Kontrolle des Wiedergabestatus.

Mehr als element.animate()

Nach der Aktualisierung ist die Web Animations API jedoch nicht mehr auf mit element.animate() erstellte Animationen beschränkt. 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 es mit element.animate() oder mit 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. Anschließend erstellen Sie zwei neue Animationseffekte für die Deckkraft, um den Cross-Fade-Effekt zu aktivieren. Lösche die Kopie, sobald der Cross-Fade abgeschlossen ist.

Animationen mit Versprechen orchestrieren

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

  • Mit animation.ready kannst du warten, bis ausstehende Änderungen wirksam werden, also das Umschalten zwischen verschiedenen Wiedergabesteuerungsmethoden wie Wiedergabe und Pause.
  • Mit animation.finished können Sie benutzerdefinierten JavaScript-Code ausführen, wenn eine Animation abgeschlossen ist.

Wir bleiben bei unserem Beispiel 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 bei einem untergeordneten Element:

Transformationen und Deckkraft auf ein ö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 das mühsam nachzubilden, insbesondere wenn mehrere Elemente mit individuellen, aber sequenziellen Animationen versehen werden. Sie müssten ein @keyframe verwenden, die richtigen Zeitprozente für das Platzieren der Animationen herausfinden und animation-delay verwenden, bevor Sie die Animationen in der Sequenz auslösen.

Beispiel: Wiedergabe, Pause und Rückspulen

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. Auf diese Weise kannst du eine reibungslosere und kontextbezogene Interaktion für unser modales Fenster schaffen.

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 Promises kannst du dann warten, bis alle abgeschlossen sind, bevor du sie abspielst. 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 ‑Frame und keine Startposition. Dies ist ein Beispiel für die Verwendung von partiellen 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 von der aktuellen zugrunde liegenden Position abgeleitet.

Neue Übergänge können ausgelöst werden, während die vorhandenen noch ausgeführt werden. 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:

Ein Kometenschweif wird animiert, wenn die Maus bewegt wird. 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 zusammengesetzten Reihenfolge, die ebenfalls beendet sind.
  3. Die neuen Animationen animieren dieselben Eigenschaften.

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 verfolgen, ob eine Animation aktiv, persistent oder entfernt ist.
  • animation.commitStyles() aktualisiert den Stil eines Elements basierend auf dem zugrunde liegenden Stil sowie alle Animationen des Elements 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 Kompositmodi können Entwickler unterschiedliche Animationen schreiben und die Kombination von Effekten steuern. Es werden jetzt drei Composite-Modi unterstützt: 'replace' (Standardmodus), 'add' und 'accumulate'.

Wenn Sie Animationen zusammenstellen, kann ein Entwickler kurze, unterschiedliche Effekte schreiben und sie kombinieren. Im folgenden Beispiel wenden wir auf jedes Feld einen Keyframe für Drehung und Skalierung an. Die einzige Anpassung ist der als Option hinzugefügte Kompositionsmodus:

Eine Demo, die die Standard-, Additions- und Aggregationsmodi zeigt. Demo auf 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 zu den Feinheiten dieser zusammengesetzten Modi finden Sie in der Web Animations-Spezifikation unter Die Enumerationen „CompositeOperation“ und „CompositeOperationOrAuto“.

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: