Signatur
Beschreibung
Die Eigenschaft targetRayMode eines XRInputSource-Objekts gibt an, auf welche Weise der Zielstrahl (target ray) dieser Eingabequelle erzeugt wird. Der Strahl selbst ist über inputSource.targetRaySpace und XRFrame.getPose() abrufbar. Wie er entsteht, hängt aber von der Hardware ab, und davon hängt wiederum ab, ob und wie du ihn darstellen solltest.
Mögliche Werte:
"gaze": Der Strahl geht vom Kopf bzw. von den Augen des Nutzers aus und zeigt in Blickrichtung. Typisch für Headsets ohne Controller, etwa Cardboard mit Tipp-Taste. Einen sichtbaren Strahl zeichnet man hier meist nicht, nur ein Fadenkreuz (Reticle) am Treffpunkt."tracked-pointer": Der Strahl stammt von einem erfassten Controller oder einer erfassten Hand und folgt deren Ausrichtung. Hier zeichnet man gewöhnlich einen sichtbaren Laserstrahl vom Controller aus."screen": Die Eingabe erfolgt per Tippen auf den Bildschirm, z. B. bei Smartphone-AR. Der Strahl geht von der Kamera durch den berührten Punkt. Er existiert nur während der Berührung und wird nicht gezeichnet."transient-pointer": Eine kurzlebige Eingabe, die vom Betriebssystem aus einer Absicht abgeleitet wird, etwa Blick plus Fingertipp auf der Apple Vision Pro. Den Strahl sollte man aus Datenschutzgründen nicht dauerhaft anzeigen.
Nutze targetRayMode, um Darstellung und Interaktion an das Eingabegerät anzupassen: sichtbarer Strahl, Fadenkreuz oder gar keine Visualisierung. Der Wert ist für eine bestimmte Eingabequelle fest. Wird ein Controller gewechselt, feuert die Sitzung inputsourceschange mit neuen XRInputSource-Objekten.
Rückgabewert
XRTargetRayMode, der angibt, wie der Zielstrahl der Eingabequelle erzeugt wird.Beispiele
Strahl-Darstellung je nach Eingabemodus wählen
// Innerhalb der Render-Schleife einer laufenden XRSession
const onXRFrame = (time, frame) => {
const session = frame.session;
session.requestAnimationFrame(onXRFrame);
for (const source of session.inputSources) {
const pose = frame.getPose(source.targetRaySpace, refSpace);
if (!pose) continue;
switch (source.targetRayMode) {
case 'tracked-pointer':
drawLaserBeam(pose.transform); // sichtbarer Strahl vom Controller
drawCursorAtHit(pose.transform);
break;
case 'gaze':
drawCursorAtHit(pose.transform); // nur Fadenkreuz, kein Strahl
break;
case 'screen':
case 'transient-pointer':
// keinen Strahl zeichnen – Eingabe ist nur kurzzeitig aktiv
break;
}
}
};
Neue Eingabequellen protokollieren
session.addEventListener('inputsourceschange', (event) => {
for (const source of event.added) {
console.log(`Neu: ${source.handedness} / ${source.targetRayMode}`);
}
for (const source of event.removed) {
console.log(`Entfernt: ${source.targetRayMode}`);
}
});
Treffertest nur bei Bildschirm-Tipp in AR
session.addEventListener('select', (event) => {
const { inputSource, frame } = event;
if (inputSource.targetRayMode !== 'screen') return;
const pose = frame.getPose(inputSource.targetRaySpace, refSpace);
if (pose) {
const { x, y, z } = pose.transform.position;
console.log(`Tipp-Strahl beginnt bei ${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)}`);
}
});
// Wichtig · Fallstricke
- Schreibgeschützt: Wenn du der Eigenschaft einen Wert zuweist, wird das ignoriert, im Strict Mode gibt es einen
TypeError. - Nicht nur zwei Werte abfragen:
"transient-pointer"kam erst später in die Spezifikation. Code, der nur"gaze"und"tracked-pointer"berücksichtigt, bricht auf neuen Geräten wie der Apple Vision Pro. Behandle unbekannte Werte immer mit einem sinnvollen Standardverhalten. - Kurzlebige Quellen: Eingabequellen vom Typ
"screen"und"transient-pointer"tauchen insession.inputSourcesnur während der Interaktion auf. Speichere sie nicht dauerhaft. - Datenschutz: Bei
"transient-pointer"bildet der Strahl den Blick des Nutzers ab. Visualisiere oder protokolliere ihn nicht außerhalb der eigentlichen Auswahl. - Kompatibilität: Die WebXR-API gibt es nur in sicheren Kontexten (HTTPS), vor allem in Chromium-Browsern und XR-Headset-Browsern. Firefox und Safari auf dem Desktop unterstützen sie nicht. Prüfe vorher mit
navigator.xr?.isSessionSupported().