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.
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:
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.
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
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:
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:
- Die Animation ist beendet.
- Es gibt eine oder mehrere Animationen in der Zusammenstellung, die ebenfalls abgeschlossen sind.
- 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:
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:
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: