Start · Sprachen · JavaScript · Referenz · XRInputSourceEvent

XRInputSourceEvent

Schnittstelle

Ereignis der WebXR Device API, das eine Aktion an einem XR-Eingabegerät meldet, etwa einen Controller-Trigger, einen Griff oder eine Pinch-Geste.

seit JavaScript WebXR Device API; Chromium-Browser 79+, Meta Quest Kategorie: webapi

Signatur

interface XRInputSourceEvent extends Event

Beschreibung

XRInputSourceEvent ist der Ereignistyp, den eine XRSession auslöst, wenn der Nutzer mit einem Eingabegerät eine primäre Aktion oder eine Squeeze-Aktion ausführt. Eingabegeräte sind zum Beispiel Handcontroller, Handtracking, Blicksteuerung oder der Bildschirmtipp bei Smartphone-AR. Dazu gehören folgende Ereignisse:

  • selectstart, select, selectend – primäre Aktion, etwa Trigger drücken, Pinch-Geste oder Tippen auf den Bildschirm
  • squeezestart, squeeze, squeezeend – Greifaktion, etwa die Grifftaste am Controller

Zusätzlich zu den Eigenschaften von Event hat das Ereignis zwei schreibgeschützte Eigenschaften. frame ist ein XRFrame, der genau zum Zeitpunkt der Aktion gilt. inputSource ist die auslösende XRInputSource. Mit event.frame.getPose(event.inputSource.targetRaySpace, refSpace) ermittelt man, wohin der Nutzer im Moment der Aktion gezeigt hat. Damit lassen sich Objekte auswählen, Raycasts ausführen oder Objekte greifen.

Das Ereignis wird in der Regel nicht selbst erzeugt, sondern vom Browser ausgelöst. Der Konstruktor new XRInputSourceEvent(type, init) ist vor allem für Tests und Polyfills gedacht. Handler registriert man mit session.addEventListener("select", handler) oder über die Eigenschaften session.onselect, session.onsqueeze usw.

Parameter

Name Typ Default Beschreibung
$type Pflicht string Name des Ereignisses, z. B. "select", "selectstart", "selectend", "squeeze", "squeezestart", "squeezeend".
$eventInitDict Pflicht XRInputSourceEventInit Objekt mit den Pflichtfeldern frame (XRFrame) und inputSource (XRInputSource) sowie optional den EventInit-Feldern bubbles, cancelable und composed.

Rückgabewert

Typ
XRInputSourceEvent
Beschreibung
Das Ereignisobjekt mit den schreibgeschützten Eigenschaften frame (XRFrame) und inputSource (XRInputSource).

Beispiele

Auswahl per select-Ereignis mit Pose des Zielstrahls

const startXR = async () => {
  const session = await navigator.xr.requestSession("immersive-vr");
  const refSpace = await session.requestReferenceSpace("local");

  session.addEventListener("select", (event) => {
    // event ist ein XRInputSourceEvent
    const { frame, inputSource } = event;
    const pose = frame.getPose(inputSource.targetRaySpace, refSpace);
    if (pose) {
      const { x, y, z } = pose.transform.position;
      console.log(`Auswahl mit ${inputSource.handedness}-Hand bei`, x.toFixed(2), y.toFixed(2), z.toFixed(2));
    }
  });
};

document.querySelector("#vr-button").addEventListener("click", startXR);
Auswahl mit right-Hand bei 0.21 1.35 -0.40

Objekte greifen und loslassen mit squeezestart/squeezeend

const heldObjects = new Map(); // XRInputSource -> Objekt

const onSqueezeStart = (event) => {
  const target = findObjectNear(event.frame, event.inputSource); // eigene Hilfsfunktion
  if (target) {
    heldObjects.set(event.inputSource, target);
    console.log("Gegriffen:", target.name);
  }
};

const onSqueezeEnd = (event) => {
  const obj = heldObjects.get(event.inputSource);
  if (obj) {
    heldObjects.delete(event.inputSource);
    console.log("Losgelassen:", obj.name);
  }
};

session.addEventListener("squeezestart", onSqueezeStart);
session.addEventListener("squeezeend", onSqueezeEnd);

// Beim Beenden aufräumen
session.addEventListener("end", () => {
  session.removeEventListener("squeezestart", onSqueezeStart);
  session.removeEventListener("squeezeend", onSqueezeEnd);
});
Gegriffen: Würfel Losgelassen: Würfel

Handler über on-Properties und Unterscheidung des Zielstrahl-Modus

session.onselectstart = (event) => {
  // "tracked-pointer" (Controller), "gaze" (Blick), "screen" (Smartphone-AR), "transient-pointer"
  console.log("Start:", event.inputSource.targetRayMode);
};

session.onselectend = (event) => {
  console.log("Ende:", event.type, event.inputSource.profiles[0] ?? "unbekannt");
};
Start: tracked-pointer Ende: selectend oculus-touch-v3

// Wichtig · Fallstricke

  • Gültigkeit von frame: Der XRFrame aus dem Ereignis ist nur während des Handler-Aufrufs aktiv. Wer ihn speichert und später oder asynchron (z. B. nach await) getPose() aufruft, erhält einen InvalidStateError. Posen also sofort im Handler auslesen.
  • Kein Ersatz für Gamepad-Abfrage: Die Ereignisse melden nur die primäre Aktion und die Greifaktion. Weitere Tasten, Thumbsticks und analoge Werte fragt man in jedem Frame über inputSource.gamepad ab.
  • select nach Abbruch: Wird eine Aktion abgebrochen, etwa weil das Tracking verloren geht oder der Controller getrennt wird, kommt nur selectend bzw. squeezeend ohne vorheriges select bzw. squeeze. Zustände wie „gegriffen“ deshalb in …end aufräumen.
  • Transiente Eingaben: Bei targetRayMode \"screen\" oder \"transient-pointer\" existiert die Eingabequelle nur für die Dauer der Aktion.
  • Kompatibilität und Sicherheit: Nur in sicheren Kontexten (HTTPS) verfügbar. Unterstützt in Chromium-Browsern (Chrome, Edge, Samsung Internet) und im Meta Quest Browser; Firefox und Safari auf dem Desktop unterstützen WebXR nicht. Eine immersive Sitzung braucht eine Nutzeraktion und kann per Permissions-Policy (xr-spatial-tracking) gesperrt sein.