Signatur
Beschreibung
Der Konstruktor XRInputSourceEvent() erstellt ein Ereignisobjekt vom Typ XRInputSourceEvent. Solche Ereignisse beschreiben Aktionen an einem WebXR-Eingabegerät, zum Beispiel einem Controller, einer getrackten Hand oder einem Blick-/Tipp-Eingabemechanismus. Der Browser verschickt sie selbst an die XRSession, und zwar als selectstart, select, selectend, squeezestart, squeeze und squeezeend.
Im normalen Anwendungscode rufen Sie den Konstruktor selten selbst auf, weil der User Agent diese Ereignisse erzeugt. Nützlich ist er vor allem für Tests, Simulationen (z. B. Tastatur- oder Maus-Fallback, der eine Controller-Auswahl nachahmt) und Event-Weiterleitung in eigenen Abstraktionsschichten oder Engines.
Das Initialisierungsobjekt muss sowohl frame (ein XRFrame) als auch inputSource (eine XRInputSource) enthalten. Beide Objekte lassen sich nicht selbst konstruieren, sondern stammen aus einer laufenden XRSession. Deshalb kann man den Konstruktor sinnvoll nur innerhalb einer aktiven XR-Sitzung einsetzen, typischerweise im requestAnimationFrame-Callback.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses, z. B. "select", "selectstart", "selectend", "squeeze", "squeezestart" oder "squeezeend". Eigene Namen sind ebenfalls erlaubt. |
|
| $eventInitDict Pflicht | XRInputSourceEventInit | Initialisierungsobjekt. Es erbt von EventInit (bubbles, cancelable, composed) und enthält außerdem:
|
Rückgabewert
XRInputSourceEvent mit den schreibgeschützten Eigenschaften frame und inputSource. Die Eigenschaft isTrusted ist false.Beispiele
Ereignis im Animations-Frame erzeugen
// Voraussetzung: aktive immersive Sitzung
const session = await navigator.xr.requestSession('immersive-vr');
const refSpace = await session.requestReferenceSpace('local');
session.requestAnimationFrame((time, frame) => {
const [source] = session.inputSources;
if (!source) return;
const event = new XRInputSourceEvent('select', {
frame,
inputSource: source
});
console.log(event.type, event.inputSource.handedness, event.isTrusted);
});
Tastatur-Fallback: Leertaste simuliert eine Controller-Auswahl
let pendingSelect = false;
window.addEventListener('keydown', (e) => {
if (e.code === 'Space') pendingSelect = true;
});
const onFrame = (time, frame) => {
const session = frame.session;
const source = [...session.inputSources]
.find((s) => s.targetRayMode === 'tracked-pointer');
if (pendingSelect && source) {
pendingSelect = false;
// Synthetisches select an die Sitzung schicken
session.dispatchEvent(new XRInputSourceEvent('select', {
frame,
inputSource: source
}));
}
session.requestAnimationFrame(onFrame);
};
session.requestAnimationFrame(onFrame);
Echte und synthetische Ereignisse gemeinsam behandeln
session.addEventListener('select', (event) => {
const pose = event.frame.getPose(
event.inputSource.targetRaySpace,
refSpace
);
if (pose) {
const { x, y, z } = pose.transform.position;
console.log(`Auswahl (${event.isTrusted ? 'echt' : 'simuliert'}) bei`,
x.toFixed(2), y.toFixed(2), z.toFixed(2));
}
});
// Wichtig · Fallstricke
- Kompatibilität: Die WebXR Device API gibt es nur in sicheren Kontexten (HTTPS). Unterstützt wird sie vor allem von Chromium-Browsern und dem Meta Quest Browser. Firefox (Desktop) und Safari unterstützen sie nicht oder nur eingeschränkt, daher vorher mit
'XRInputSourceEvent' in windowundnavigator.xrprüfen. - Nicht frei konstruierbar:
frameundinputSourcesind Pflichtfelder. Fehlen sie, wirft der Konstruktor einenTypeError. Außerhalb einer laufenden Sitzung gibt es keine gültigen Werte dafür. - Frame-Gültigkeit: Ein
XRFrameist nur während seines Animations-Callbacks (bzw. während der Ereignisverarbeitung) aktiv. Ruft man danachevent.frame.getPose()auf, wird eineInvalidStateError-Ausnahme ausgelöst. Synthetische Ereignisse sollten Sie deshalb synchron im selben Callback verschicken. - Kein Nutzer-Aktivierungsersatz: Selbst erzeugte Ereignisse haben
isTrusted === falseund zählen nicht als Nutzergeste, etwa für das Abspielen von Audio oder für Vollbild. - Unter Node.js gibt es die Klasse nicht.