Signatur
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 Bildschirmsqueezestart,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
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);
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);
});
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");
};
// Wichtig · Fallstricke
- Gültigkeit von
frame: DerXRFrameaus dem Ereignis ist nur während des Handler-Aufrufs aktiv. Wer ihn speichert und später oder asynchron (z. B. nachawait)getPose()aufruft, erhält einenInvalidStateError. 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.gamepadab. selectnach Abbruch: Wird eine Aktion abgebrochen, etwa weil das Tracking verloren geht oder der Controller getrennt wird, kommt nurselectendbzw.squeezeendohne vorherigesselectbzw.squeeze. Zustände wie „gegriffen“ deshalb in…endaufrä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.