Komplexe Animationen synchronieren
CSS-Keyframes-Animationen lassen sich nicht einfach miteinander synchronisieren. »Starte eine Animation, wenn eine andere Animation abgelaufen ist« läßt sich nur bedingt durch Verzögerungen (animation-delay) realisieren. CSS-Animationen wirken nur auf individuelle Elemente und erkennen keine Abhängigkeiten zwischen dem Verhalten einzelner Elemente. CSS kann nicht feststellen, ob eine Animation noch läuft oder beendet ist. Für das Zurücksetzen und Neustarten der CSS-Animation muss JavaScript eingesetzt werden.
Bei den klassischen Javascript-Animationen von setTimeout über setInterval hin bis zu requestAnimationFrame fehlte das Easing für sanftes Anlaufen und Beschleunigen oder das blitzschnelle Anlaufen und langsames Auslaufen.
Das Web Animation API ist mit der Methode elem.animate (keyframes, options) der Brückenschlag zwischen CSS-@keyframes und JavaScript.
finished.then – die nächste Animation starten
Per se starten CSS-Animationen mit dem Laden der Seite. Eine CSS-@keyframes-Animation wäre schon abgelaufen, bevor der Benutzer bis zu dieser Stelle scrollt. Neben dem animation-delay gibt es keine Möglichkeit, Animationen in Abhängigkeit von anderen Animationen zu starten.
<div id="herz"> <div id="quader"></div> <div id="kreis1"></div> <div id="kreis2"></div> </div>
animate() hat zwei Argumente: ein Array von Keyframes und ein Objekt für die Steuerung des zeitlichen Ablaufs.
+-- Javascript Object mit Eigenschaften | wie Dauer, Iterationen, Verzögerung | animate (keyframes, options) | | +-- Array von Keyframes
animation().finished gibt ein Promise zurück, das auslöst, wenn die Animation abgespielt wurde.
document.querySelector ("#kreis1").animate ( [ { transform: "translate(500px)", opacity: "0" }, { transform: "translate(calc(100% - 75px))", opacity: "1" } ], { duration: 1000, fill: "forwards", easing: "ease-in-out"} ).finished.then (() => { document.querySelector ("#kreis2").animate ( [ { transform: "translateY(-500px)", opacity: "0" }, { transform: "translateY(calc(100% - 225px))", opacity: "1" } ], { duration: dauer, fill: "forwards", easing: "ease-in-out" } ).finished.then (() => { document.querySelector ("#herz").animate ( [ { transform: "rotate(0deg)" }, { transform: "rotate(-45deg)" } ], { duration: dauer, fill: "forwards", easing: "ease-in-out" } ).finished.then (() => { document.querySelector ("#reset").removeAttribute ("disabled") document.querySelector ("#restart").setAttribute ("disabled", "disabled") }); }); });
Das läßt sich übersichtlicher strukturieren, wenn das Array der Keyframes in eine Variable gesetzt wird.
const kreisTransforms = [ { transform: "translate(500px)", opacity: "0" }, { transform: "translate(calc(100% - 75px))", opacity: "1" } ]; … document.querySelector ("#kreis1").animate ( kreisTransforms, { duration: 1000, fill: "forwards", easing: "ease-in-out"} )
Mehr zu Animationen JavaScript und CSS
- CSS animation-delay – @keyframes-Animationen verzögern und synchronisieren
- CSS transform translate – um ein Element über die verfügbare Breite zu verschieben reicht es nicht, das Element selber zu animieren bzw. transformieren.
- Javascript Web Animation API – während den klassischen Techniken der Animation mit JavaScript noch das Easing fehlte, borgt das Web Animation API bei den @keyframes-Animationen auch das elegante Easing.