Window: requestAnimationFrame() Methode
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Die window.requestAnimationFrame()
Methode teilt dem Browser mit, dass Sie eine Animation durchführen möchten. Sie fordert den Browser auf, eine vom Benutzer bereitgestellte Rückruffunktion vor dem nächsten Neuzeichnen aufzurufen.
Die Häufigkeit der Aufrufe der Rückruffunktion stimmt im Allgemeinen mit der Bildschirmaktualisierungsrate überein. Die häufigste Aktualisierungsrate beträgt 60 Hz (60 Zyklen/Bilder pro Sekunde), aber 75 Hz, 120 Hz und 144 Hz sind ebenfalls weit verbreitet. requestAnimationFrame()
Aufrufe werden in den meisten Browsern pausiert, wenn sie in Hintergrund-Tabs oder versteckten <iframe>
s ausgeführt werden, um die Leistung und die Akkulaufzeit zu verbessern.
Hinweis:
Ihre Rückruffunktion muss requestAnimationFrame()
erneut aufrufen, wenn Sie ein weiteres Bild animieren möchten. requestAnimationFrame()
ist einmalig.
Warnung: Achten Sie darauf, immer das erste Argument (oder eine andere Methode zur Ermittlung der aktuellen Uhrzeit) zu verwenden, um zu berechnen, wie weit die Animation in einem Frame fortschreiten wird — andernfalls läuft die Animation auf Bildschirmen mit hoher Bildwiederholrate schneller ab. Weitere Informationen finden Sie in den unten stehenden Beispielen.
Syntax
requestAnimationFrame(callback)
Parameter
callback
-
Die Funktion, die aufgerufen wird, wenn es Zeit ist, Ihre Animation für das nächste Neuzeichnen zu aktualisieren. Diese Rückruffunktion erhält ein einzelnes Argument:
timestamp
-
Ein
DOMHighResTimeStamp
, der die Endzeit des Renderings des vorherigen Bildes angibt (basierend auf der Anzahl von Millisekunden seit dem Zeitursprung). Der Zeitstempel ist eine Dezimalzahl, in Millisekunden, jedoch mit einer minimalen Genauigkeit von 1 Millisekunde. FürWindow
Objekte (nichtWorkers
) ist es gleichdocument.timeline.currentTime
. Dieser Zeitstempel wird zwischen allen Fenstern geteilt, die auf demselben Agenten ausgeführt werden (alle Fenster mit gleichem Ursprung und, was noch wichtiger ist, iframe mit gleichem Ursprung) — was das Synchronisieren von Animationen über mehrererequestAnimationFrame
Rückrufe ermöglicht. Der Zeitstempelwert ähnelt auch dem Aufruf vonperformance.now()
zu Beginn der Rückruffunktion, ist jedoch nie derselbe Wert.Wenn mehrere Rückrufe, die durch
requestAnimationFrame()
in einem einzigen Frame eingereiht wurden, beginnen zu feuern, erhält jeder denselben Zeitstempel, obwohl während der Berechnung jeder vorhergehenden Rückrufbelastung Zeit vergangen ist.
Rückgabewert
Ein long
Integer-Wert, die Anforderungs-ID, die den Eintrag in der Rückrufliste eindeutig identifiziert. Dies ist ein von null verschiedener Wert, aber Sie sollten keine weiteren Annahmen über seinen Wert treffen. Diesen Wert können Sie an window.cancelAnimationFrame()
übergeben, um die Aktualisierungs-Rückrufanforderung abzubrechen.
Beispiele
In diesem Beispiel wird ein Element für 2 Sekunden (2000 Millisekunden) animiert. Das Element bewegt sich mit einer Geschwindigkeit von 0,1px/ms nach rechts, sodass seine relative Position (in CSS-Pixel) in Abhängigkeit von der seit Beginn der Animation verstrichenen Zeit (in Millisekunden) mit 0.1 * elapsed
berechnet werden kann. Die Endposition des Elements ist 200px (0.1 * 2000
) rechts von seiner Ausgangsposition.
const element = document.getElementById("some-element-you-want-to-animate");
let start;
function step(timestamp) {
if (start === undefined) {
start = timestamp;
}
const elapsed = timestamp - start;
// Math.min() is used here to make sure the element stops at exactly 200px
const shift = Math.min(0.1 * elapsed, 200);
element.style.transform = `translateX(${shift}px)`;
if (shift < 200) {
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
Die folgenden drei Beispiele zeigen verschiedene Ansätze zum Festlegen des Nullpunkts in der Zeit, die Basislinie zur Berechnung des Fortschritts Ihrer Animation in jedem Frame. Wenn Sie eine Synchronisation mit einer externen Uhr vornehmen möchten, wie z.B. BaseAudioContext.currentTime
, dann ist die höchste verfügbare Präzision die Dauer eines einzelnen Frames, 16,67ms @60Hz. Das Zeitstempel-Argument des Rückrufs stellt das Ende des vorherigen Frames dar, sodass der früheste Zeitpunkt, zu dem Ihre neu berechneten Werte gerendert werden, im nächsten Frame liegt.
Dieses Beispiel wartet, bis der erste Rückruf ausgeführt wird, um zero
zu setzen. Wenn Ihre Animation bei Beginn auf einen neuen Wert springt, müssen Sie sie auf diese Weise strukturieren. Wenn Sie nichts Externes, wie z.B. Audio, synchronisieren müssen, wird dieser Ansatz empfohlen, da einige Browser eine Verzögerung von mehreren Frames zwischen dem initialen Aufruf von requestAnimationFrame()
und dem ersten Aufruf der Rückruffunktion haben.
let zero;
requestAnimationFrame(firstFrame);
function firstFrame(timestamp) {
zero = timestamp;
animate(timestamp);
}
function animate(timestamp) {
const value = (timestamp - zero) / duration;
if (value < 1) {
element.style.opacity = value;
requestAnimationFrame((t) => animate(t));
} else element.style.opacity = 1;
}
Dieses Beispiel verwendet document.timeline.currentTime
, um einen Nullwert vor dem ersten Aufruf von requestAnimationFrame
zu setzen. document.timeline.currentTime
stimmt mit dem timestamp
Argument überein, sodass der Nullwert dem Zeitstempel des 0ten Frames entspricht.
const zero = document.timeline.currentTime;
requestAnimationFrame(animate);
function animate(timestamp) {
const value = (timestamp - zero) / duration; // animation-timing-function: linear
if (value < 1) {
element.style.opacity = value;
requestAnimationFrame((t) => animate(t));
} else element.style.opacity = 1;
}
Dieses Beispiel animiert mit performance.now()
anstelle des Zeitstempelwerts des Rückrufs. Sie könnten dies verwenden, um eine etwas höhere Synchronisationsgenauigkeit zu erreichen, obwohl der zusätzliche Grad der Präzision variabel und nicht sehr groß ist. Hinweis: Dieses Beispiel erlaubt Ihnen nicht, Animationsrückrufe zuverlässig zu synchronisieren.
const zero = performance.now();
requestAnimationFrame(animate);
function animate() {
const value = (performance.now() - zero) / duration;
if (value < 1) {
element.style.opacity = value;
requestAnimationFrame((t) => animate(t));
} else element.style.opacity = 1;
}
Spezifikationen
Specification |
---|
HTML Standard # dom-animationframeprovider-requestanimationframe |
Browser-Kompatibilität
BCD tables only load in the browser