| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/de/docs/Web/API/Web_Animations_API/Using_the_Web_Animations_API | [Back] [Original] |
Get to know MDN better
Dieser Inhalt wurde automatisch aus dem Englischen bersetzt, und kann Fehler enthalten. Erfahre mehr ber dieses Experiment.
Die Web Animations API ermglicht es uns, Animationen zu erstellen und deren Wiedergabe mit JavaScript zu steuern. Dieser Artikel wird Sie mit unterhaltsamen Demos und Tutorials, die von "Alice im Wunderland" inspiriert sind, in die richtige Richtung lenken.
Die Web Animations API ffnet das Animations-Engine des Browsers fr Entwickler und Manipulationen durch JavaScript. Diese API wurde entwickelt, um sowohl CSS-Animationen als auch CSS-bergnge zu implementieren und lsst Raum fr zuknftige Animationseffekte. Es ist eine der leistungsfhigsten Mglichkeiten, im Web zu animieren, da der Browser seine eigenen internen Optimierungen ohne Tricks, Zwang oder Window.requestAnimationFrame() vornehmen kann.
Mit der Web Animations API knnen wir interaktive Animationen aus Stylesheets nach JavaScript verlagern und Prsentation von Verhalten trennen. Wir mssen uns nicht mehr auf DOM-lastige Techniken wie das Schreiben von CSS-Eigenschaften und das Scoping von Klassen auf Elemente verlassen, um die Wiedergaberichtung zu steuern. Und im Gegensatz zu rein deklarativem CSS ermglicht JavaScript es uns, Werte von Eigenschaften bis hin zu Dauern dynamisch festzulegen. Fr den Aufbau benutzerdefinierter Animationsbibliotheken und die Erstellung interaktiver Animationen knnte die Web Animations API das perfekte Werkzeug sein. Schauen wir uns an, was sie leisten kann!
Diese Seite enthlt eine Reihe von Beispielen, die die Web Animations API nutzen und von Alice im Wunderland inspiriert sind. Diese Beispiele werden mit freundlicher Genehmigung von Rachel Nabors erstellt und geteilt. Die vollstndige Suite von Beispielen ist auf CodePen verfgbar; hier prsentieren wir die fr unsere Dokumentation relevanten.
Eine der bekannteren Mglichkeiten, um in die Web Animations API einzusteigen, ist der Start mit etwas, das die meisten Webentwickler schon einmal verwendet haben: CSS-Animationen. CSS-Animationen haben eine vertraute Syntax, die sich gut zu Demonstrationszwecken eignet.
Hier ist eine fallende Animation, die in CSS geschrieben wurde und Alice zeigt, wie sie in das Kaninchenloch fllt, das nach Wunderland fhrt:
<div class="wrapper">
<div id="tunnel"></div>
<div id="alice">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
<path
d="M110.1 2.7h8.9c3.4.4 6.7.8 10.1 1.3 9.8 1.5 17.8 6.4 24.5 13.7.4.5 1.9.6 2.5.3 6.8-4.4 13.9-8.2 21.9-9.9 1.3-.3 3.4-1.2 3.7 1.5.6 4.9 1.4 9.9 1.7 14.8.3 4.4.1 8.7.1 12.2 2.1 1.5 4.6 2.3 5.5 4 4.2 8.4 3.2 17.6 3.1 26.6 0 1.2-.4 3.3.1 3.6 10.3 4.9 20.7 9.6 31.1 14.4 2.5-4.9-2.3-16-15.8-14.4.6-.5 1.4-1.1 2.2-1.1 2.5.1 4.9.4 7.4.7 6 .8 10.9 3.7 14.6 8.4 1.2 1.5 1.6 4.2 1.1 6.1-.7 3.2-3.7 4-7.1 4.1 4.5 3.5 6.5 8.1 6.8 13.3.6 9.4-1.1 18.6-4.8 27.1-3.9 8.8-5.2 17.5-3.3 26.8.6 3.2 1.2 7 .2 9.9-2 6.2-7.8 8.6-13.4 10.9-3 1.2-7.4 1.2-6.3 6.3.8 3.7-.4 4 .2 4.5 5.8 5.8 11.8 11.5 17.6 17.3 1.7 1.7 3 3.8 4.3 5.5-1.1.4-1.8.7-2.4 1 7.5 5.8 14.9 11.6 22.4 17.4 4.3-4.3 8.6-9 13.3-13.2 8.1-7.3 16.7-14 24.5-21.7 3.3-3.3 4.9-8.2 7.4-12.3.3-.4 1.3-.9 1.6-.7 4.6 2.7 6.8 7.2 7.9 12.1 1.3 5.7 1.6 11.6 2.3 17.1 4.2-.2 8.8-.8 13.4-.4 2 .1 4.6 1.8 5.5 3.5 2.2 4.3 3.8 8.9 5.3 13.5 3.7 11.5 6.9 23.2 10.7 34.7 1.7 5.1 3.4 10.4 8.6 13.4.5.3.5 2.7 0 3.1-3.3 2.5-6.9 4.6-10.5 7 2 5.8 4.3 12.6 6.7 19.6.7-.8 1.4-1.6 2.1-2.3 1.9-1.9 3.5-1.6 4.2 1.2.7 3 1.3 6.2 1.5 9.3.3 7.3.4 14.6.6 21.9 0 .4.2.8.5 1.2 3.6 4.7 7.1 9.3 10.7 14 1.7 2.3 3 5.4 5.3 6.6 5.5 2.7 11.5 4.4 17.3 6.6v.7c-.4.3-.7.8-1.2 1-5.8 2.1-11.6 4.3-17.5 6.2-4.2 1.3-8.4 2-12.4-1.2-1.8-1.5-3.9-2.6-5.8-3.8 0 2.3.1 4.4-.1 6.4-.1.8-.7 2.2-1.2 2.2-2.6.2-5.3.1-7.9.1-1.1 0-2.7.3-3.2-.3-1-1.2-2.1-2.9-2.1-4.4-.1-5.2.1-10.4.3-15.6.1-1.8 1.5-3.9.9-5.4-1.7-4.3-4-8.4-6.1-12.5-2.4-4.6-6.4-9.1-1.2-14.3.3-.3.3-1.3 0-1.7-4.7-6.5-9.5-13.1-14.4-19.5-1.2-1.5-2.9-3.7-4.4-3.7-6.7.1-13.4.8-20.1 1.3-.7.1-1.6.2-1.9.6-7.1 9.1-14 18.3-21.1 27.4-1.3 1.7-2.9 3.4-4.3 5 1.7.6 3.3 1.1 4.8 1.7.6.2 1.3.5 1.6 1 .2.3-.1 1.1-.4 1.5-2 2.6-4.1 5.2-6.1 7.8-4.3 5.3-8.7 10.5-13 15.9-.8 1-1.5 2.4-1.6 3.6-.2 5.4-.1 10.7-.1 16.1 0 1.5-.7 3.6.1 4.5 2.4 3 5.3 5.5 7.9 8.2 1.6 1.7 3 3.5 4.6 5.5-2.6.2-4.5.3-6.4.4h-3.7c-4.8-1.4-9.8-2.5-14.5-4.3-3.5-1.4-7.8-2.5-8-7.7-.1-2.1-.2-4.3-.4-6.7-1 1.1-1.7 2.1-2.6 2.9-.3.3-1 .4-1.3.2-1.9-1.1-3.7-2.2-5.5-3.4-1.7-1.1-4.5-1.6-3.5-4.5 2.3-6.5 6.4-11.6 12.7-14.9.6-.3 1.3-.9 1.6-1.5 3.9-8.2 7.8-16.4 11.8-24.6.7-1.5.4-4.5 3.8-3.8.2.1 1.2-3.1 1.8-4.9-2.8 1.5-5 2.9-7.4 3.9-7.4 3-14.7 6.4-23.1 5.6-8.5-.7-16.2-3.4-23.2-8-9.9-6.7-14.2-17-17.5-27.9-.5-1.7-.5-5.1-3.5-1.6-.1.2-.4.2-.6.3-2.5 1.7-5.4 3-6 6.5-.4 2.3-1 4.6-1.5 7-2.9 13.2-4.2 26.4-2.5 39.9 1.7 13.1 9.2 21.3 21 26.3 2.4 1 4.9 1.9 7.5 2.9-2.1.9-3.9 1.9-5.8 2.3-10.2 2.5-20.5 4.9-30.8 7.1-1.9.4-4.9.7-5.9-.3-6.4-6.5-8.9-14.8-8.3-23.7.7-9.6 2.1-19.2 3.9-28.6 2.2-11.5 6.1-22.5 11.7-32.9.7-1.3 2-3.1 1.6-4.1-1.8-4.6-4.5-8.9-6.2-13.6-2-5.7-4.2-11.6-1.2-17.8.1-.1-.3-.5-.5-.8 7.6.7 12.8 5.3 17.7 10.2-1.3-8.5-2.6-17.2-3.9-25.8 0-.3-.2-.7-.4-.9-6.7-5.5-13.3-11.2-17-19.2-2.6-5.7-4.3-11.8-6.3-17.7-.6-1.6.2-3.4-2.2-4.8-5.9-3.5-10.3-8.6-10.3-16 0-1.8 1.2-5 2.2-5.1 8.3-1.2 16.4-.1 23.8 4.2 2.4 1.4 4.9 2.7 8.1 4.4-.4-8.8-.8-16.2-1.2-23.6-4.2.9-8.6.9-11.5-2-3.3-3.3-5.4-7.8-7.9-11.8-1.1-1.7-2-3.6-3.5-6.4-3.8 10.3-7.4 19.9-10.8 29.1-.3-.6-1.1-1.7-1.5-2.9-3.5-10-2.8-20.2-1.1-30.3 1.2-7.4 4.3-14.6 3.1-22.4-.2-1.1.2-2.3.3-3.4-22.1 17.6-38.8 38.4-42.9 67.4-4 28-2.8 54.8 13.5 79.1-36.3-13.8-53-48.6-58.3-84.1-3 8-15 16.3-22.4 16.6v-.2c2.1-2.9 11.1-10.6 7-30.2-1.3-10.7-4.1-21.2-5.1-31.9-1-10.9-1-21.9-.5-32.9.3-11.6 3.8-22.7 8.6-33.2 5.7-12.5 13.5-23.8 23-33.6 5.6-5.8 11.9-11 18.2-16.1 8.6-6.8 17.7-12.9 28.2-16.5 5.1-1.9 10.4-3 15.7-4.5zm96.4 221.9c-.4.9-1.2 2-1.1 3 .5 7.6 1.2 15.2 2 22.7.2 2.1 0 4.8 3.3 5.5 3.3.7 6.6 1.8 9.9 2.6.3.1.9-.1 1.1-.4 3.8-4.8 7.5-9.6 10.9-14-8.4-6.1-17.1-12.6-26.1-19.4zm-23.1-42.5v6.3c1.9-2 3.6-3.9 5.3-5.7-1.7-.2-3.5-.4-5.3-.6z" />
</svg>
</div>
</div>
Beachten Sie, dass sich der Hintergrund bewegt, Alice sich dreht und ihre Farbe sich versetzt zu ihrer Drehung ndert. In diesem Tutorial konzentrieren wir uns nur auf Alice. Sie knnen den vollstndigen Quellcode berprfen, indem Sie auf "Play" im Codeblock klicken. Hier ist das vereinfachte CSS, das Alices Animation steuert:
#alice {
animation: alice-tumbling infinite 3s linear;
}
@keyframes alice-tumbling {
0% {
color: black;
transform: rotate(0) translate3d(-50%, -50%, 0);
}
30% {
color: #431236;
}
100% {
color: black;
transform: rotate(360deg) translate3d(-50%, -50%, 0);
}
}
#tunnel {
animation: tunnel-fly 1s linear infinite;
}
@keyframes tunnel-fly {
100% {
transform: translate3d(0, -300px, 0);
}
}
#alice {
color: #431236;
width: 25%;
position: absolute;
top: 50%;
left: 50%;
transform-origin: 0 0;
transform: rotate(0) translate3d(-50%, -50%, 0);
backface-visibility: hidden;
will-change: transform, color;
}
path {
fill: currentColor;
}
#tunnel {
background:
url("/shared-assets/images/examples/web-animations/bg-tunnel-border-left.svg")
repeat-y,
url("/shared-assets/images/examples/web-animations/bg-tunnel-border-right.svg")
repeat-y 100% 100%,
url("/shared-assets/images/examples/web-animations/bg-tunnel-specks.png"),
#6c373f;
margin: 0 auto;
height: calc(100% + 300px);
width: 60%;
min-width: 400px;
backface-visibility: hidden;
will-change: transform;
}
.wrapper {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
}
body {
background: black;
}
html,
body {
height: 100%;
}
Dies ndert Alices Farbe und ihre Transformationsdrehung ber 3 Sekunden mit einer konstanten (linearen) Rate und wiederholt sich unendlich. Im @keyframes-Block sehen wir, dass sich Alices Farbe 30 % des Weges durch jede Schleife (etwa nach 0,9 Sekunden) von Schwarz zu einem tiefen Burgunderrot ndert und dann bis zum Ende der Schleife wieder zurck wechselt.
Jetzt versuchen wir die gleiche Animation mit der Web Animations API zu erstellen.
Das Erste, was wir brauchen, ist die Erstellung eines Keyframe Object entsprechend unserem CSS-@keyframes-Block:
const aliceTumbling = [
{ transform: "rotate(0) translate3d(-50%, -50%, 0)", color: "black" },
{ color: "#431236", offset: 0.3 },
{ transform: "rotate(360deg) translate3d(-50%, -50%, 0)", color: "black" },
];
Hier verwenden wir ein Array, das mehrere Objekte enthlt. Jedes Objekt reprsentiert einen Key aus dem ursprnglichen CSS. Im Gegensatz zu CSS muss die Web Animations API jedoch nicht explizit ber die Prozentstze entlang der Animation fr jedes erscheinende Key informiert werden. Sie wird die Animation automatisch in gleiche Teile basierend auf der Anzahl der angegebenen Keys unterteilen. Das bedeutet, dass ein Keyframe-Objekt mit drei Keys den mittleren Key 50 % des Weges durch jede Schleife der Animation abspielt, sofern nicht anders angegeben.
Wenn wir explizit den Versatz eines Keys von den anderen Keys festlegen mchten, knnen wir einen Offset direkt im Objekt spezifizieren, getrennt von der Deklaration durch ein Komma. Im obigen Beispiel, um sicherzustellen, dass Alices Farbnderung bei 30% (nicht 50%) erfolgt, geben wir offset: 0.3 an.
Derzeit sollten mindestens zwei Keyframes spezifiziert sein (die Start- und Endzustnde der Animationssequenz darstellend). Wenn Ihre Keyframe-Liste nur einen Eintrag hat, kann Element.animate() in einigen Browsern einen NotSupportedError DOMException werfen, bis sie aktualisiert werden.
Zusammenfassend sind die Keys standardmig gleichmig verteilt, es sei denn, Sie spezifizieren einen Offset auf einem Key. Praktisch, nicht wahr?
Wir mssen auch ein Objekt von Timingeigenschaften erstellen, das den Werten in Alices Animation entspricht:
const aliceTiming = {
duration: 3000,
iterations: Infinity,
};
Hier sind einige Unterschiede zu erkennen, wie quivalente Werte in CSS reprsentiert werden:
setTimeout() und Window.requestAnimationFrame(), akzeptiert die Web Animations API nur Millisekunden.iterations und nicht iteration-count heit.Hinweis:
Es gibt eine Reihe kleiner Unterschiede zwischen der in CSS-Animationen verwendeten Terminologie und der in Web-Animationen verwendeten. Beispielsweise verwendet Web Animations nicht den String "infinite", sondern stattdessen das JavaScript-Schlsselwort Infinity. Und anstelle von timing-function verwenden wir easing. Hier geben wir keinen easing-Wert an, weil, im Gegensatz zu CSS-Animationen, bei denen der Standardwert der animation-timing-function ease ist, bei der Web Animations API das Standard-easing linear also das, was wir hier wollen.
Jetzt ist es Zeit, sie beide mit der Methode Element.animate() zusammenzufhren:
document.getElementById("alice").animate(aliceTumbling, aliceTiming);
Und boom: Die Animation beginnt zu spielen:
document
.getElementById("tunnel")
.animate(
[
{ transform: "translate3d(0, 0, 0)" },
{ transform: "translate3d(0, -300px, 0)" },
],
{
duration: 1000,
iterations: Infinity,
},
);
Die animate()-Methode kann auf jedem DOM-Element aufgerufen werden, das mit CSS animiert werden knnte. Und sie kann auf verschiedene Weisen geschrieben werden. Anstatt Objekte fr Keyframes und Timingeigenschaften zu erstellen, knnten wir ihre Werte direkt bergeben, so wie hier:
document.getElementById("alice").animate(
[
{ transform: "rotate(0) translate3d(-50%, -50%, 0)", color: "black" },
{ color: "#431236", offset: 0.3 },
{ transform: "rotate(360deg) translate3d(-50%, -50%, 0)", color: "black" },
],
{
duration: 3000,
iterations: Infinity,
},
);
Noch mehr, wenn wir nur die Dauer der Animation und nicht ihre Iterationen angeben wollten (standardmig iteriert eine Animation einmal), knnten wir einfach die Millisekunden allein bergeben:
document.getElementById("alice").animate(
[
{ transform: "rotate(0) translate3d(-50%, -50%, 0)", color: "black" },
{ color: "#431236", offset: 0.3 },
{ transform: "rotate(360deg) translate3d(-50%, -50%, 0)", color: "black" },
],
3000,
);
Whrend wir CSS-Animationen mit der Web Animations API schreiben knnen, liegt der wahre Nutzen der API in der Manipulation der Wiedergabe der Animation. Die Web Animations API bietet mehrere ntzliche Methoden zur Steuerung der Wiedergabe. Lassen Sie uns einen Blick auf das Pausieren und Spielen von Animationen im "Follow the White Rabbit"-Beispiel werfen:
In diesem Beispiel hat der weie Hase eine Animation, die ihn in ein Kaninchenloch lsst. Sie wird nur ausgelst, wenn der Benutzer darauf klickt.
<div class="wrapper">
<div class="page">
<div class="background"></div>
<div id="rabbit">Click the rabbit's ears!</div>
<div class="foreground"></div>
<p>
She was just in time to see him pop down a hole between a great tree's
roots.
</p>
</div>
</div>
#rabbit {
background: url("/shared-assets/images/examples/web-animations/park5_rabbit.png")
0 0 / 100% 100%;
cursor: pointer;
position: absolute;
top: 15%;
left: 60%;
width: 14.64844%;
padding-top: 31.00586%;
}
body {
background: black;
}
.wrapper {
max-width: 133.33vh;
margin: 0 auto;
}
.page {
background: #431236;
height: 0;
overflow: hidden;
padding-top: 75%;
position: relative;
text-indent: 100%;
white-space: nowrap;
}
.foreground {
height: 100%;
background: url("/shared-assets/images/examples/web-animations/bg_park5_2.png")
no-repeat 100% 100% / 100% auto;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
pointer-events: none;
}
.background {
background: url("/shared-assets/images/examples/web-animations/bg_park5_1.png")
no-repeat 0 0 / 100% auto;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
Wir knnen den Hasen wie gewohnt mit der animate()-Methode animieren:
const whiteRabbit = document.getElementById("rabbit");
const rabbitDownAnimation = whiteRabbit.animate(
[{ transform: "translateY(0%)" }, { transform: "translateY(100%)" }],
{ duration: 3000, fill: "forwards" },
);
Die Methode Element.animate() wird sofort ausgefhrt, nachdem sie aufgerufen wurde. Um zu verhindern, dass der Kuchen sich selbst isst, bevor der Benutzer die Mglichkeit hatte, darauf zu klicken, rufen wir sofort nach der Definition Animation.pause() darauf auf, wie folgt:
rabbitDownAnimation.pause();
Hinweis:
Alternativ knnen Sie rabbitDownAnimation mit dem Animation()-Konstruktor definieren, das nicht spielt, bis Sie play() aufrufen.
Wir knnen jetzt die Methode Animation.play() verwenden, um sie auszufhren, wann immer wir bereit sind. Speziell wollen wir es mit einer Klickaktion verknpfen. Wir knnen dies ber folgendes erreichen:
whiteRabbit.addEventListener("click", downHeGoes);
whiteRabbit.addEventListener("touchstart", downHeGoes);
function downHeGoes(event) {
whiteRabbit.removeEventListener("click", downHeGoes);
whiteRabbit.removeEventListener("touchstart", downHeGoes);
rabbitDownAnimation.play();
}
Wenn ein Benutzer auf den Hasen klickt oder mit dem Finger darauf drckt, knnen wir jetzt downHeGoes aufrufen, um alle Animationen abzuspielen.
Zustzlich zum Pausieren und Abspielen knnen wir die folgenden Animation-Methoden verwenden:
Animation.finish() springt zum Ende der Animation.Animation.cancel() bricht die Animation ab und entfernt deren Effekte.Animation.reverse() setzt die Wiedergaberate (Animation.playbackRate](/de/docs/Web/API/Animation/playbackRate)) der Animation auf einen negativen Wert, sodass sie rckwrts luft.Schauen wir uns zuerst playbackRate an eine negative playbackRate lsst eine Animation rckwrts laufen.
In Durch den Spiegel reist Alice zu einer Welt, in der sie laufen muss, um an Ort und Stelle zu bleiben und doppelt so schnell laufen muss, um sich vorwrts zu bewegen! Im Beispiel "Red Queen's Race" laufen Alice und die Rote Knigin, um an Ort und Stelle zu bleiben:
<div class="wrapper">
<div class="sky"></div>
<div class="earth">
<div id="red-queen-and-alice">
<img
id="red-queen-and-alice-sprite"
src="/shared-assets/images/examples/web-animations/sprite_running-alice-queen_small.png"
srcset="
/shared-assets/images/examples/web-animations/sprite_running-alice-queen.png 2x
"
alt="Alice and the Red Queen running to stay in place." />
</div>
</div>
<div class="scenery" id="foreground1">
<img
id="palm3"
src="/shared-assets/images/examples/web-animations/palm3_small.png"
srcset="/shared-assets/images/examples/web-animations/palm3.png 2x"
alt="" />
</div>
<div class="scenery" id="foreground2">
<img
id="bush"
src="/shared-assets/images/examples/web-animations/bush_small.png"
srcset="/shared-assets/images/examples/web-animations/bush.png 2x"
alt="" />
<img
id="w_rook_upright"
src="/shared-assets/images/examples/web-animations/w_rook_upright_small.png"
srcset="
/shared-assets/images/examples/web-animations/w_rook_upright.png 2x
"
alt="" />
</div>
<div class="scenery" id="background1">
<img
id="r_pawn_upright"
src="/shared-assets/images/examples/web-animations/r_pawn_upright_small.png"
srcset="
/shared-assets/images/examples/web-animations/r_pawn_upright.png 2x
"
alt="" />
<img
id="w_rook"
src="/shared-assets/images/examples/web-animations/w_rook_small.png"
srcset="/shared-assets/images/examples/web-animations/w_rook.png 2x"
alt="" />
<img
id="palm1"
src="/shared-assets/images/examples/web-animations/palm1_small.png"
srcset="/shared-assets/images/examples/web-animations/palm1.png 2x"
alt="" />
</div>
<div class="scenery" id="background2">
<img
id="r_pawn"
src="/shared-assets/images/examples/web-animations/r_pawn_small.png"
srcset="/shared-assets/images/examples/web-animations/r_pawn.png 2x"
alt="" />
<img
id="r_knight"
src="/shared-assets/images/examples/web-animations/r_knight_small.png"
srcset="/shared-assets/images/examples/web-animations/r_knight.png 2x"
alt="" />
<img
id="palm2"
src="/shared-assets/images/examples/web-animations/palm2_small.png"
srcset="/shared-assets/images/examples/web-animations/palm2.png 2x"
alt="" />
</div>
</div>
* {
user-select: none;
}
img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.scenery {
width: 100%;
height: 50%;
position: absolute;
bottom: 0;
left: 0;
}
#foreground1,
#foreground2 {
z-index: 1;
}
#foreground2,
#background2 {
transform: translateX(100%);
}
#palm3 {
top: 0;
left: 10%;
}
#w_rook_upright {
top: 30%;
left: 75%;
}
#r_pawn {
top: 10%;
left: 15%;
}
#w_rook {
top: 10%;
left: 80%;
}
#r_pawn_upright {
top: 5%;
left: 30%;
}
#r_knight {
top: 0;
left: 70%;
}
#palm2 {
top: -15%;
left: 90%;
}
#palm1 {
top: -15%;
left: 40%;
}
#bush {
top: 55%;
left: 20%;
}
#red-queen-and-alice {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
width: 80%;
max-width: 450px;
z-index: 1;
}
#red-queen-and-alice::before {
content: " ";
display: block;
padding-top: 87%;
}
#red-queen-and-alice img {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.sky,
.earth {
position: absolute;
left: 0;
height: 50vh;
width: 100%;
}
.earth {
background: #eb125d
url("/shared-assets/images/examples/web-animations/bg_earth.jpg") repeat-x 0
0 / 100% auto;
bottom: 0;
}
.sky {
background: #246e89
url("/shared-assets/images/examples/web-animations/bg_sky.jpg") repeat-x
100% 100% / auto 100%;
top: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.wrapper {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
}
const background1 = document.getElementById("background1");
const background2 = document.getElementById("background2");
const foreground1 = document.getElementById("foreground1");
const foreground2 = document.getElementById("foreground2");
const redQueenAliceSprite = document.getElementById(
"red-queen-and-alice-sprite",
);
/* Background animations */
const sceneryFrames = [
{ transform: "translateX(100%)" },
{ transform: "translateX(-100%)" },
];
const sceneryTimingBackground = {
duration: 36000,
iterations: Infinity,
};
const sceneryTimingForeground = {
duration: 12000,
iterations: Infinity,
};
const background1Movement = background1.animate(
sceneryFrames,
sceneryTimingBackground,
);
background1Movement.currentTime =
background1Movement.effect.getComputedTiming().duration / 2;
const background2Movement = background2.animate(
sceneryFrames,
sceneryTimingBackground,
);
const foreground1Movement = foreground1.animate(
sceneryFrames,
sceneryTimingForeground,
);
foreground1Movement.currentTime =
foreground1Movement.effect.getComputedTiming().duration / 2;
const foreground2Movement = foreground2.animate(
sceneryFrames,
sceneryTimingForeground,
);
const spriteFrames = [
{ transform: "translateY(0)" },
{ transform: "translateY(-100%)" },
];
const redQueenAlice = redQueenAliceSprite.animate(spriteFrames, {
easing: "steps(7, end)",
direction: "reverse",
duration: 600,
playbackRate: 1,
iterations: Infinity,
});
Da kleine Kinder im Gegensatz zu automatisierten Schachfiguren schnell ermden, verlangsamt sich Alice stndig. Wir knnen dies tun, indem wir ein Abklingen auf ihre playbackRate der Animation einstellen. Wir verwenden updatePlaybackRate() anstelle von playbackRate direkt zu setzen, da dies ein reibungsloses Update erzeugt:
setInterval(() => {
// Make sure the playback rate never falls below .4
if (redQueenAlice.playbackRate > 0.4) {
redQueenAlice.updatePlaybackRate(redQueenAlice.playbackRate * 0.9);
}
adjustBackgroundPlayback();
}, 1000);
Aber wenn man auf sie klickt oder tippt, werden sie durch Multiplikation ihrer playbackRate beschleunigt:
function goFaster() {
// But you can speed them up by giving the screen a click or a tap.
redQueenAlice.updatePlaybackRate(redQueenAlice.playbackRate * 1.1);
adjustBackgroundPlayback();
}
document.addEventListener("click", goFaster);
document.addEventListener("touchstart", goFaster);
Auch die Hintergrundelemente haben playbackRates, die beim Klick oder Tap beeinflusst werden. Ihre Wiedergaberaten werden aus Alice's abgeleitet, siehe unten. Was passiert, wenn Sie Alice und die Rote Knigin doppelt so schnell laufen lassen? Was passiert, wenn sie langsamer werden?
/* Alice tires so easily!
Every so many seconds, reduce their playback rate so they slow a little.
*/
const sceneries = [
foreground1Movement,
foreground2Movement,
background1Movement,
background2Movement,
];
function adjustBackgroundPlayback() {
// If Alice and the Red Queen are running at a speed of 0.81.2,
// the background doesn't move.
// But if they fall under 0.8, the background slides backwards
if (redQueenAlice.playbackRate < 0.8) {
sceneries.forEach((anim) => {
anim.updatePlaybackRate(-redQueenAlice.playbackRate / 2);
});
} else if (redQueenAlice.playbackRate > 1.2) {
sceneries.forEach((anim) => {
anim.updatePlaybackRate(redQueenAlice.playbackRate / 2);
});
} else {
sceneries.forEach((anim) => {
anim.updatePlaybackRate(0);
});
}
}
adjustBackgroundPlayback();
Ein hufiger Anwendungsfall beim Animieren von Elementen ist, den Endzustand der Animation nach deren Abschluss beizubehalten. Eine manchmal verwendete Methode dafr ist das Setzen des fill mode der Animation auf forwards. Es wird jedoch nicht empfohlen, Fill-Modi zu verwenden, um den Effekt einer Animation unbegrenzt beizubehalten, aus zwei Grnden:
Ein besserer Ansatz ist die Verwendung der Methode Animation.commitStyles(). Dies schreibt die berechneten Werte der aktuellen Stile der Animation in das style-Attribut ihres Zielelements, danach kann das Element normal umgestylt werden.
Es ist mglich, eine groe Anzahl von Animationen auf demselben Element auszulsen. Wenn sie unbegrenzt sind (d.h. forward-filling), kann dies zu einer riesigen Animationsliste fhren, die ein Speicherleck verursachen knnte. Aus diesem Grund entfernen Browser automatisch fllende Animationen, nachdem sie durch neuere Animationen ersetzt wurden, es sei denn, der Entwickler gibt ausdrcklich an, sie zu behalten.
Animationen werden entfernt, wenn alle folgenden Bedingungen erfllt sind:
fill ist forwards, wenn sie vorwrts luft, backwards, wenn sie rckwrts luft, oder both).fill trotzdem noch in Kraft ist.)DocumentTimeline; andere Zeitleisten wie scroll-timeline knnen rckwrts laufen.)AnimationEffect der Animation wird durch eine andere Animation berschrieben, die ebenfalls alle obigen Bedingungen erfllt. (Typischerweise, wenn zwei Animationen die gleiche Stileigenschaft des gleichen Elements setzen, berschreibt die zuletzt erstellte die andere.)Die ersten vier Bedingungen stellen sicher, dass ohne Eingreifen durch JavaScript-Code der Effekt der Animation sich nie ndern oder enden wird. Die letzte Bedingung stellt sicher, dass die Animation nie tatschlich den Stil eines Elements beeinflussen wird: sie wurde vollstndig ersetzt.
Wenn die Animation automatisch entfernt wird, wird das remove-Ereignis der Animation ausgelst.
Um zu verhindern, dass der Browser Animationen automatisch entfernt, rufen Sie die Methode persist() der Animation auf.
Die Eigenschaft replaceState der Animation wird removed sein, wenn die Animation entfernt wurde, persisted, wenn Sie persist() auf die Animation angewendet haben, oder active, andernfalls.
Stellen Sie sich andere Mglichkeiten vor, wie wir playbackRate verwenden knnten, z. B. zur Verbesserung der Barrierefreiheit fr Benutzer mit vestibulren Strungen, indem wir ihnen ermglichen, Animationen auf einer gesamten Website zu verlangsamen. Das ist mit CSS ohne Neuberechnung der Dauern in jeder CSS-Regel unmglich, aber mit der Web Animations API knnen wir die Methode Document.getAnimations verwenden, um jede Animation auf der Seite zu durchlaufen und ihre playbackRates zu halbieren, so wie hier:
document.getAnimations().forEach((animation) => {
animation.updatePlaybackRate(animation.playbackRate * 0.5);
});
Mit der Web Animations API mssen Sie nur eine kleine Eigenschaft ndern!
Ein weiteres Problem, das mit CSS-Animationen allein schwer zu lsen ist, ist die Schaffung von Abhngigkeiten von Werten, die von anderen Animationen bereitgestellt werden. Im Beispiel des "Growing and Shrinking Alice"-Spiels haben Sie vielleicht bemerkt, dass die Dauer des Kuchens etwas merkwrdig ist:
document.getElementById("eat-me-sprite").animate([], {
duration: aliceChange.effect.getComputedTiming().duration / 2,
});
Um zu verstehen, was hier passiert, schauen wir uns die Animation von Alice an:
const aliceChange = document
.getElementById("alice")
.animate(
[
{ transform: "translate(-50%, -50%) scale(.5)" },
{ transform: "translate(-50%, -50%) scale(2)" },
],
{
duration: 8000,
easing: "ease-in-out",
fill: "both",
},
);
Alices Animation lsst sie von der Hlfte ihrer Gre auf das Doppelte ihrer Gre ber 8 Sekunden anwachsen. Dann pausieren wir sie:
aliceChange.pause();
Wenn wir sie am Anfang ihrer Animation pausiert gelassen htten, wrde sie bei der Hlfte ihrer vollen Gre beginnen, als ob sie die ganze Flasche schon ausgetrunken htte! Wir wollen den "Abspielkopf" ihrer Animation in der Mitte setzen, also ist sie schon zur Hlfte fertig. Wir knnten dies tun, indem wir ihre Animation.currentTime auf 4 Sekunden einstellen, so wie hier:
aliceChange.currentTime = 4000;
Aber whrend wir an dieser Animation arbeiten, knnten wir Alices Dauer oft ndern. Wre es nicht besser, wenn wir ihre currentTime dynamisch einstellen, damit wir nicht zwei nderungen gleichzeitig vornehmen mssen? Tatschlich knnen wir dies tun, indem wir auf die Eigenschaft Animation.effect von aliceChange verweisen, die ein Objekt mit allen Details des/der Effekte(s), die auf Alice aktiv sind, zurckgibt:
aliceChange.currentTime = aliceChange.effect.getComputedTiming().duration / 2;
effect ermglicht es uns, auf die Keyframes und Timingeigenschaften der Animation zuzugreifen aliceChange.effect.getComputedTiming() zeigt auf Alices Timing-Objekt das enthlt ihre duration. Wir knnen ihre Dauer halbieren, um den Mittelpunkt ihrer Animationszeitleiste zu erhalten, und sie auf normale Gre setzen. Jetzt knnen wir ihre Animation in beide Richtungen umkehren und abspielen, um sie wachsen oder schrumpfen zu lassen!
Und wir knnen dasselbe tun, wenn wir die Dauer von Kuchen und Flasche einstellen:
const drinking = document
.getElementById("liquid")
.animate([{ height: "100%" }, { height: "0" }], {
fill: "forwards",
duration: aliceChange.effect.getComputedTiming().duration / 2,
});
drinking.pause();
Jetzt sind alle drei Animationen mit nur einer Dauer verknpft, die wir leicht an einem Ort ndern knnen.
Wir knnen auch die Web Animations API verwenden, um die aktuelle Zeit der Animation zu ermitteln. Das Spiel endet, wenn Ihnen der Kuchen zum Essen oder die Flasche leer geht. Welche Vignette den Spielern prsentiert wird, hngt davon ab, wie weit Alice in ihrer Animation war, ob sie zu gro wird und nicht mehr durch die kleine Tr passen kann oder zu klein ist und nicht den Schlssel zur Tr erreichen kann. Wir knnen herausfinden, ob sie am groen oder kleinen Ende ihrer Animation ist, indem wir die currentTime ihrer Animation erhalten und sie durch ihre activeDuration teilen:
const endGame = () => {
// get Alice's timeline's playhead location
const alicePlayhead = aliceChange.currentTime;
const aliceTimeline = aliceChange.effect.getComputedTiming().activeDuration;
// stops Alice's and other animations
stopPlayingAlice();
// depending on which third it falls into
const aliceHeight = alicePlayhead / aliceTimeline;
if (aliceHeight <= 0.333) {
// Alice got smaller!
//
} else if (aliceHeight >= 0.666) {
// Alice got bigger!
//
} else {
// Alice didn't change significantly
//
}
};
CSS-Animationen und -bergnge haben ihre eigenen Ereignis-Listener, und diese sind auch mit der Web Animations API mglich:
onfinish ist der Ereignishandler fr das finish-Ereignis und kann manuell mit finish() ausgelst werden.oncancel ist der Ereignishandler fr das cancel-Ereignis und kann mit cancel() ausgelst werden.Hier setzen wir die Callbacks fr den Kuchen, die Flasche und Alice, um die Funktion endGame auszulsen:
// When the cake or bottle runs out
nommingCake.onfinish = endGame;
drinking.onfinish = endGame;
// Alice reaches the end of her animation
aliceChange.onfinish = endGame;
Noch besser, die Web Animations API bietet auch ein finished Promise, das erfllt wird, wenn die Animation abgeschlossen ist, oder abgelehnt, wenn sie abgebrochen wird.
Dies sind die grundlegenden Funktionen der Web Animations API. Jetzt sollten Sie bereit sein, "ins Kaninchenloch" des Animierens im Browser zu springen und bereit sein, Ihre eigenen Animationsexperimente zu schreiben!
Der Bauplan fr ein besseres Internet.
Teile dieses Inhalts sind 19982026 von einzelnen mozilla.org-Mitwirkenden. Inhalte sind verfgbar unter einer Creative-Commons-Lizenz.
| Web Proxy Viewer | New URL | Original Page |