Start · Sprachen · JavaScript · Referenz · XRSession.visibilityState

XRSession.visibilityState

Eigenschaft

Schreibgeschützter String, der angibt, ob der Inhalt einer <code>XRSession</code> gerade sichtbar ist und ob er den Eingabefokus hat: <code>"visible"</code>, <code>"visible-blurred"</code> oder <code>"hidden"</code>.

seit JavaScript WebXR Device API – Chrome/Edge 79+, Samsung Intern Kategorie: webapi

Signatur

XRSession.visibilityState

Beschreibung

Die schreibgeschützte Eigenschaft visibilityState einer XRSession zeigt, wie sichtbar die immersive Szene gerade für den Benutzer ist. Mögliche Werte:

  • "visible" – Die Szene ist sichtbar und hat den Fokus. Die Anwendung bekommt Eingaben und sollte ganz normal rendern.
  • "visible-blurred" – Die Szene ist noch zu sehen, aber nicht mehr im Fokus. Das passiert zum Beispiel, wenn ein System-Overlay oder ein Berechtigungsdialog darübergelegt wird. Eingaben kommen nicht an, und die Bildrate von requestAnimationFrame() kann gedrosselt sein. Posen können ungenauer werden oder ganz ausbleiben, um keine Daten preiszugeben.
  • "hidden" – Die Szene ist nicht sichtbar. Callbacks von requestAnimationFrame() werden nicht ausgeführt, bis die Szene wieder sichtbar ist.

Wenn sich der Wert ändert, wird auf der Session das Ereignis visibilitychange ausgelöst. Darauf reagieren Sie zum Beispiel so: Spiellogik anhalten, Audio stummschalten, rechenintensive Physik aussetzen oder einen Pausenhinweis anzeigen.

Die Eigenschaft ist das WebXR-Gegenstück zu document.visibilityState aus der Page Visibility API. Sie bezieht sich aber nur auf die XR-Darstellung auf dem Headset und nicht auf den Browser-Tab.

Rückgabewert

Typ
"visible" | "visible-blurred" | "hidden"
Beschreibung
Ein String aus dem Aufzählungstyp XRVisibilityState, der den aktuellen Sichtbarkeits- und Fokuszustand der Session beschreibt.

Beispiele

Aktuellen Zustand nach dem Session-Start abfragen

const startXR = async () => {
  if (!navigator.xr || !(await navigator.xr.isSessionSupported('immersive-vr'))) {
    console.log('Immersives VR wird nicht unterstützt');
    return;
  }
  const session = await navigator.xr.requestSession('immersive-vr');
  console.log('Sichtbarkeit:', session.visibilityState);
};

// requestSession braucht eine Benutzeraktion
document.querySelector('#enter-vr').addEventListener('click', startXR);
Sichtbarkeit: visible

Spiel bei Fokusverlust pausieren

let paused = false;

const handleVisibility = (event) => {
  const { visibilityState } = event.session;
  switch (visibilityState) {
    case 'visible':
      paused = false;
      console.log('Fortsetzen');
      break;
    case 'visible-blurred':
      paused = true; // Szene weiter zeichnen, aber Logik anhalten
      console.log('Pausiert (Overlay aktiv)');
      break;
    case 'hidden':
      paused = true;
      console.log('Versteckt – Audio stumm');
      break;
  }
};

const session = await navigator.xr.requestSession('immersive-vr');
session.addEventListener('visibilitychange', handleVisibility);
Pausiert (Overlay aktiv) Fortsetzen

Im Render-Loop nur bei vollem Fokus aktualisieren

const onXRFrame = (time, frame) => {
  const session = frame.session;
  session.requestAnimationFrame(onXRFrame);

  if (session.visibilityState === 'visible') {
    updatePhysics(time);   // nur mit Fokus
  }
  renderScene(frame);      // bei 'visible-blurred' trotzdem zeichnen
};

const updatePhysics = (t) => { /* ... */ };
const renderScene = (frame) => { /* ... */ };

const session = await navigator.xr.requestSession('immersive-vr');
session.requestAnimationFrame(onXRFrame);

// Wichtig · Fallstricke

  • Schreibgeschützt: Wenn Sie der Eigenschaft einen Wert zuweisen, wird die Zuweisung stillschweigend ignoriert, im Strict Mode wirft sie einen TypeError. Den Zustand steuert allein der User-Agent.
  • "visible-blurred" ist nicht dasselbe wie „pausiert“: Rendern Sie in diesem Zustand weiter, sonst sieht der Benutzer ein eingefrorenes Bild oder ruckelnde Darstellung. Verlassen Sie sich außerdem nicht auf Eingaben oder genaue Posen, denn Controller-Ereignisse wie select kommen dann nicht an.
  • Bei "hidden" werden keine requestAnimationFrame()-Callbacks ausgeführt. Zeitbasierte Logik sollte deshalb nach der Rückkehr große Zeitsprünge (Delta-Zeit) abfangen.
  • Sessions vom Typ "inline" melden in der Regel dauerhaft "visible". Für die Sichtbarkeit des Tabs nutzen Sie dort document.visibilityState.
  • Kompatibilität: Unterstützt in Chromium-basierten Browsern (Chrome, Edge, Samsung Internet, Meta Quest Browser). Firefox und Safari auf dem Desktop unterstützen WebXR nicht. Die API funktioniert nur in sicheren Kontexten (HTTPS) und kann per Permissions-Policy xr-spatial-tracking gesperrt sein.