Signatur
Beschreibung
VRDisplay.cancelAnimationFrame() ist das Gegenstück zu VRDisplay.requestAnimationFrame() aus der veralteten WebVR-API. Die Methode funktioniert wie Window.cancelAnimationFrame(), bezieht sich aber auf die Bildwiederholrate des VR-Headsets statt auf die des Monitors. Während einer aktiven VR-Präsentation (nach requestPresent()) laufen Callbacks von VRDisplay.requestAnimationFrame() oft mit 90 Hz oder mehr.
Man braucht die Methode, wenn die Render-Schleife beendet werden soll, etwa beim Verlassen des VR-Modus, beim Pausieren einer Szene oder beim Abbauen einer Komponente. Übergeben wird die Kennung, die VRDisplay.requestAnimationFrame() zurückgegeben hat.
Wichtig: Kennungen von window.requestAnimationFrame() und von VRDisplay.requestAnimationFrame() gehören zu getrennten Warteschlangen. Eine Kennung muss daher immer mit dem cancelAnimationFrame() desselben Objekts abgemeldet werden, das sie erzeugt hat.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $handle Pflicht | number | Die ganzzahlige Kennung, die ein vorheriger Aufruf von VRDisplay.requestAnimationFrame() zurückgegeben hat. Unbekannte oder schon ausgeführte Kennungen werden stillschweigend ignoriert. |
Rückgabewert
undefined).Beispiele
Render-Schleife starten und stoppen
let vrDisplay = null;
let frameHandle = 0;
const drawVRScene = () => {
// Nächsten Frame direkt anmelden, damit die Schleife weiterläuft
frameHandle = vrDisplay.requestAnimationFrame(drawVRScene);
// ... WebGL-Szene rendern ...
vrDisplay.submitFrame();
};
const stopLoop = () => {
if (vrDisplay && frameHandle) {
vrDisplay.cancelAnimationFrame(frameHandle);
frameHandle = 0;
console.log('VR-Render-Schleife gestoppt');
}
};
if (navigator.getVRDisplays) {
navigator.getVRDisplays().then((displays) => {
if (displays.length > 0) {
vrDisplay = displays[0];
frameHandle = vrDisplay.requestAnimationFrame(drawVRScene);
// Nach 5 Sekunden anhalten
setTimeout(stopLoop, 5000);
}
});
} else {
console.log('WebVR wird nicht unterstützt');
}
Beim Verlassen des VR-Modus auf Fenster-Schleife wechseln
let vrDisplay;
let vrHandle = 0;
let winHandle = 0;
const renderWindow = () => {
winHandle = window.requestAnimationFrame(renderWindow);
// ... Szene für den Monitor rendern ...
};
const exitVR = async () => {
// VR-Kennung mit dem VRDisplay abmelden, nicht mit window!
vrDisplay.cancelAnimationFrame(vrHandle);
vrHandle = 0;
await vrDisplay.exitPresent();
winHandle = window.requestAnimationFrame(renderWindow);
console.log('Zurück im Fenster-Modus');
};
document.querySelector('#exit-vr')?.addEventListener('click', exitVR);
Schleife bei verdecktem Tab pausieren
const pauseOnHidden = (display, getHandle, resume) => {
document.addEventListener('visibilitychange', () => {
if (document.hidden) {
display.cancelAnimationFrame(getHandle());
console.log('Pausiert');
} else {
resume();
console.log('Fortgesetzt');
}
});
};
// Wichtig · Fallstricke
- Veraltet: WebVR und damit
VRDisplayist abgeschafft und wurde nie in allen Browsern eingeführt. Früher lief es in Firefox (Windows) und in speziellen Chromium-Builds, aktuelle Browser haben es entfernt. Für neue ProjekteXRSession.cancelAnimationFrame()aus der WebXR Device API verwenden. - Kennungen aus
window.requestAnimationFrame()lassen sich nicht mitVRDisplay.cancelAnimationFrame()abmelden, und umgekehrt geht es auch nicht. Die Warteschlangen sind getrennt. - Ruft sich der Callback selbst neu auf, muss die Kennung bei jedem Frame aktualisiert werden. Sonst wird eine veraltete Kennung abgemeldet und die Schleife läuft weiter.
- Vor dem Aufruf mit
'getVRDisplays' in navigatorprüfen, ob die API überhaupt vorhanden ist.