Web Animations API-Verbesserungen in Chromium 84

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

Veröffentlicht: 27. Mai 2020

Bei richtiger Verwendung verbessern Animationen die Wahrnehmung und Erinnerung der Nutzer an Ihre Marke, leiten 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.

Während Firefox und Safari bereits alle Funktionen der Spezifikation implementiert haben, bietet Chromium 84 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. 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 verbesserte Kontrolle über die 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.

Animationsabläufe mit Promises 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), gefolgt von einer horizontalen Transformation (scaleX) und einer Änderung der Deckkraft bei einem untergeordneten 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. So werden die Animationen in der richtigen Reihenfolge abgespielt und Sie können sogar Effekte auf verschiedene Zielelemente mit unterschiedlichen Optionen anwenden (z. B. Geschwindigkeit und Easing).

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 ermitteln 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. 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 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 auf 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 teilweisen Frames. 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.

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 entfernt jetzt alte Animationen (ermöglicht den Ersatz), wenn:

  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 Eigenschaften und Methoden, mit denen Sie die Animation noch weiter steuern können:

  • Mit animation.replaceState lässt sich nachverfolgen, ob eine Animation aktiv, beibehalten oder entfernt wurde.
  • 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 zusammenführen. 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 Drop-down-Menü als Einblendeffekt von oben auf der Seite um die volle Höhe des Menüs verschoben wird. Die zweite ist eine Mikroanimation, bei der das Menü beim Erreichen des unteren Endes leicht nach oben springt. 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 Ergänzungen sind in Planung. Weitere Informationen zu den nächsten Schritten finden Sie in diesen zukünftigen Spezifikationen: