Signatur
Beschreibung
Die Eigenschaft handedness einer XRInputSource sagt Ihnen, ob ein Controller oder eine getrackte Hand zur linken oder rechten Hand des Benutzers gehört. Ist das nicht bekannt oder ergibt es keinen Sinn, lautet der Wert "none", etwa bei Blick- oder Kopfsteuerung (targetRayMode === "gaze") oder bei Bildschirmberührungen in AR auf dem Smartphone ("screen").
Die Zuordnung brauchen Sie vor allem, um Controller-Modelle an der richtigen Hand darzustellen, um beiden Händen unterschiedliche Aufgaben zu geben (z. B. links das Menü, rechts das Werkzeug) oder um Gamepad-Tasten richtig auszuwerten. Zusammen mit profiles lässt sich über das WebXR-Input-Profiles-Register das passende 3D-Modell für jede Hand laden.
Der Wert bleibt für die gesamte Lebensdauer eines XRInputSource-Objekts gleich. Ändert sich die Händigkeit, zum Beispiel weil ein Controller in die andere Hand wechselt, entfernt der Browser die alte Eingabequelle und meldet eine neue. Beides erfahren Sie über das Event inputsourceschange der XRSession.
Rückgabewert
XRHandedness: "left" für die linke Hand, "right" für die rechte Hand, "none", wenn die Quelle keiner Hand zugeordnet ist oder die Hand unbekannt ist.Beispiele
Händigkeit aller aktiven Eingabequellen ausgeben
const session = await navigator.xr.requestSession('immersive-vr');
session.addEventListener('inputsourceschange', ({ added, removed }) => {
for (const source of added) {
console.log(`Neu: ${source.handedness} (${source.targetRayMode})`);
}
for (const source of removed) {
console.log(`Entfernt: ${source.handedness}`);
}
});
Controller nach Hand im Frame-Loop zuordnen
const controllers = { left: null, right: null, none: null };
const onFrame = (time, frame) => {
const session = frame.session;
for (const source of session.inputSources) {
if (!source.gripSpace) continue;
const pose = frame.getPose(source.gripSpace, refSpace);
if (pose) {
// Position des Controllers pro Hand merken
controllers[source.handedness] = pose.transform.position;
}
}
session.requestAnimationFrame(onFrame);
};
const refSpace = await xrSession.requestReferenceSpace('local-floor');
xrSession.requestAnimationFrame(onFrame);
Unterschiedliche Aktionen für linke und rechte Hand
xrSession.addEventListener('select', (event) => {
const { handedness } = event.inputSource;
switch (handedness) {
case 'left':
toggleMenu(); // linke Hand öffnet das Menü
break;
case 'right':
fireTool(); // rechte Hand benutzt das Werkzeug
break;
default:
selectByGaze(); // Blicksteuerung oder Bildschirm-Tap
}
});
Passendes Controller-Modell auswählen
const modelPathFor = (source) => {
const profile = source.profiles[0] ?? 'generic-trigger';
const hand = source.handedness === 'none' ? 'none' : source.handedness;
return `/models/${profile}/${hand}.glb`;
};
for (const source of xrSession.inputSources) {
console.log(modelPathFor(source));
}
// Wichtig · Fallstricke
- Nicht auf zwei Hände verlassen: Gehen Sie nicht davon aus, dass immer genau eine linke und eine rechte Quelle existieren. Es kann nur ein Controller verbunden sein, mehrere Quellen können
"none"melden, und bei Hand-Tracking kommen und gehen die Quellen je nach Sichtbarkeit der Hände. - Nicht zwischenspeichern: Der Wert ist pro Objekt unveränderlich. Wechselt ein Controller die Hand, entsteht jedoch ein neues
XRInputSource-Objekt. Speichern Sie deshalb keine Zuordnung dauerhaft, sondern reagieren Sie aufinputsourceschange. - Schreibgeschützt: Wenn Sie der Eigenschaft einen Wert zuweisen, passiert nichts; im Strict Mode wird ein
TypeErrorausgelöst. - Barrierefreiheit: Manche Menschen nutzen nur eine Hand oder sind Linkshänder. Wichtige Funktionen sollten deshalb nicht fest an eine Hand gebunden sein, oder die Belegung sollte sich umstellen lassen.
- Kompatibilität: WebXR steht nur in sicheren Kontexten (HTTPS) zur Verfügung. Chromium-basierte Browser und der Meta Quest Browser unterstützen es, Firefox und Safari auf dem Desktop nicht; Safari auf visionOS hat eine eigene Umsetzung. Prüfen Sie vorab mit
navigator.xr?.isSessionSupported().