Signatur
Beschreibung
XRSystem ist die zentrale Schnittstelle der WebXR Device API. Eine eigene Instanz legt man nicht an: Der Browser stellt genau ein Objekt über navigator.xr bereit. Darüber findet eine Webanwendung heraus, ob ein VR-Headset oder AR-fähiges Gerät vorhanden ist, und startet eine immersive oder eingebettete (inline) Sitzung.
Die Schnittstelle hat zwei Methoden:
isSessionSupported(mode)– gibt einPromise<boolean>zurück, das angibt, ob der Modus"inline","immersive-vr"oder"immersive-ar"grundsätzlich unterstützt wird. Damit lässt sich etwa ein „VR betreten“-Button nur bei vorhandener Hardware einblenden.requestSession(mode, options)– fordert eineXRSessionan. ÜberrequiredFeaturesundoptionalFeatureswerden zusätzliche Fähigkeiten verlangt, z. B."local-floor","hand-tracking","hit-test"oder"dom-overlay".
Außerdem ist XRSystem ein EventTarget und löst das Ereignis devicechange aus, wenn XR-Geräte angeschlossen oder getrennt werden. Das kann man über addEventListener("devicechange", …) oder die Eigenschaft ondevicechange abfangen, um die Unterstützung neu zu prüfen.
Üblicher Ablauf: Unterstützung prüfen, nach einer Nutzeraktion (Klick) eine Sitzung anfordern, einen WebGL-Kontext mit xrCompatible: true über XRWebGLLayer anbinden, einen Referenzraum anfordern und die Render-Schleife mit session.requestAnimationFrame() starten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $mode Pflicht | "inline" | "immersive-vr" | "immersive-ar" | Sitzungsmodus für isSessionSupported() und requestSession(). inline rendert in ein Element der Seite, die immersive-*-Modi übernehmen die Anzeige des Geräts. |
|
| $options | XRSessionInit | {} | Nur bei requestSession(): Objekt mit requiredFeatures (Array; fehlt eine davon, wird das Promise abgelehnt), optionalFeatures (Array) und je nach Feature weiteren Angaben, z. B. domOverlay: { root: element }. |
Rückgabewert
navigator.xr erreichbar (undefined, wenn der Browser WebXR nicht kennt oder der Kontext nicht sicher ist). isSessionSupported() gibt Promise<boolean> zurück, requestSession() gibt Promise<XRSession> zurück.Beispiele
Unterstützung prüfen und VR-Button einblenden
const vrButton = document.querySelector('#enter-vr');
const checkXR = async () => {
if (!('xr' in navigator)) {
vrButton.textContent = 'WebXR nicht verfügbar';
vrButton.disabled = true;
return;
}
const supported = await navigator.xr.isSessionSupported('immersive-vr');
vrButton.disabled = !supported;
vrButton.textContent = supported ? 'VR betreten' : 'Kein VR-Gerät gefunden';
console.log('immersive-vr unterstützt:', supported);
};
checkXR();
Immersive VR-Sitzung starten und Render-Schleife anbinden
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2', { xrCompatible: true });
const startVR = async () => {
// Muss aus einer Nutzeraktion heraus aufgerufen werden
const session = await navigator.xr.requestSession('immersive-vr', {
requiredFeatures: ['local-floor'],
optionalFeatures: ['hand-tracking']
});
session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });
const refSpace = await session.requestReferenceSpace('local-floor');
const onFrame = (time, frame) => {
const pose = frame.getViewerPose(refSpace);
if (pose) {
const layer = session.renderState.baseLayer;
gl.bindFramebuffer(gl.FRAMEBUFFER, layer.framebuffer);
gl.clearColor(0.1, 0.1, 0.2, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
// ... hier pro pose.views zeichnen
}
session.requestAnimationFrame(onFrame);
};
session.requestAnimationFrame(onFrame);
session.addEventListener('end', () => console.log('VR-Sitzung beendet'));
};
document.querySelector('#enter-vr').addEventListener('click', () => {
startVR().catch((err) => console.error('Start fehlgeschlagen:', err.name, err.message));
});
AR-Sitzung mit Hit-Test und DOM-Overlay anfordern
const overlay = document.querySelector('#ar-overlay');
const startAR = async () => {
if (!(await navigator.xr?.isSessionSupported('immersive-ar'))) {
console.log('AR wird nicht unterstützt');
return;
}
const session = await navigator.xr.requestSession('immersive-ar', {
requiredFeatures: ['hit-test'],
optionalFeatures: ['dom-overlay'],
domOverlay: { root: overlay }
});
console.log('Aktivierte Features:', session.enabledFeatures);
return session;
};
document.querySelector('#enter-ar').onclick = () => startAR();
Auf angeschlossene oder getrennte Geräte reagieren (devicechange)
const onDeviceChange = async () => {
const vr = await navigator.xr.isSessionSupported('immersive-vr');
console.log('Gerätewechsel – VR verfügbar:', vr);
};
navigator.xr?.addEventListener('devicechange', onDeviceChange);
// Später wieder entfernen:
// navigator.xr.removeEventListener('devicechange', onDeviceChange);
// Alternativ über die Handler-Eigenschaft:
// navigator.xr.ondevicechange = onDeviceChange;
// Wichtig · Fallstricke
- Nur in sicheren Kontexten:
navigator.xrgibt es ausschließlich über HTTPS (oderlocalhost). In iframes braucht es die Berechtigungsrichtlinieallow="xr-spatial-tracking". - Nutzeraktion nötig:
requestSession()für immersive Modi wird ohne vorherige Nutzeraktion (z. B. Klick) mitSecurityErrorabgelehnt. Außerdem ist immer nur eine immersive Sitzung gleichzeitig erlaubt – ein zweiter Versuch führt zuInvalidStateError. - Nicht unterstützte Features: Kann eine der
requiredFeaturesnicht bereitgestellt werden, wird das Promise mitNotSupportedErrorabgelehnt. Alles, was nicht zwingend nötig ist, gehört deshalb inoptionalFeatures. Was tatsächlich aktiv ist, zeigtsession.enabledFeatures. isSessionSupported()ist keine Garantie: Eintrueheißt nur, dass der Modus grundsätzlich möglich ist. Die Sitzung kann trotzdem scheitern, z. B. wenn der Nutzer die Berechtigung ablehnt.- WebGL-Kompatibilität: Der WebGL-Kontext muss mit
xrCompatible: trueangelegt oder vorher mitawait gl.makeXRCompatible()vorbereitet werden, sonst schlägtnew XRWebGLLayer()fehl. - Browser-Unterstützung: Gut unterstützt in Chromium-Browsern (Chrome/Edge ab 79, Chrome auf Android für AR mit ARCore) und im Meta Quest Browser. Firefox unterstützt WebXR nicht, Safari nur unter visionOS. Immer per Feature-Erkennung (
'xr' in navigator) prüfen. Für ältere Umgebungen gibt es das WebXR Polyfill. - Datenschutz: Tracking-Daten gelten als sensibel. Browser zeigen daher Einwilligungsdialoge an, besonders bei AR und Hand-Tracking.