Signatur
Beschreibung
Das Interface GamepadPose gehört zu den Erweiterungen der Gamepad API und liefert die räumliche Lage eines bewegungserfassten Controllers, etwa eines VR-Handcontrollers. Man bekommt es nicht über einen Konstruktor, sondern liest es über die Eigenschaft Gamepad.pose eines Gamepad-Objekts aus navigator.getGamepads() aus.
Eine Pose enthält alle Werte als schreibgeschützte Eigenschaften:
hasOrientation/hasPosition:boolean. Gibt an, ob der Controller Orientierung bzw. Position überhaupt melden kann.position:Float32Array[x, y, z] in Metern, relativ zum Ursprung des Tracking-Raums.linearVelocity/linearAcceleration: [x, y, z] in m/s bzw. m/s².orientation: Quaternion [x, y, z, w].angularVelocity/angularAcceleration: [x, y, z] in rad/s bzw. rad/s².
Jede Vektor-Eigenschaft kann null sein, wenn die Hardware den Wert nicht liefert. Die Werte bilden immer nur einen Moment ab. Wer eine aktuelle Pose braucht, muss das Gamepad in jedem Frame (z. B. in requestAnimationFrame) neu abfragen.
Das Interface stammt aus der Zeit von WebVR, das inzwischen eingestellt ist. Für neue Projekte ist die WebXR Device API gedacht. Dort liefern XRInputSource und XRFrame.getPose() die gleichen Informationen.
Rückgabewert
Gamepad.pose gelesen. Liefert ein GamepadPose-Objekt oder null, wenn das Gamepad keine Pose-Daten hat.Beispiele
Pose eines Controllers in jedem Frame auslesen
const formatVec = (v) => v ? Array.from(v, (n) => n.toFixed(2)).join(', ') : 'n/a';
const loop = () => {
for (const pad of navigator.getGamepads()) {
if (!pad || !pad.pose) continue;
const { pose } = pad;
if (pose.hasPosition) {
console.log(`${pad.id} Position: ${formatVec(pose.position)}`);
}
if (pose.hasOrientation) {
console.log(`${pad.id} Orientierung: ${formatVec(pose.orientation)}`);
}
}
requestAnimationFrame(loop);
};
requestAnimationFrame(loop);
Fähigkeiten beim Verbinden prüfen
window.addEventListener('gamepadconnected', (event) => {
const { gamepad } = event;
if (!('pose' in gamepad) || !gamepad.pose) {
console.log(`${gamepad.id}: keine Pose-Daten verfügbar`);
return;
}
const { hasPosition, hasOrientation } = gamepad.pose;
const typ = hasPosition && hasOrientation ? '6DoF'
: hasOrientation ? '3DoF (nur Rotation)'
: 'ohne Tracking';
console.log(`${gamepad.id}: ${typ}`);
});
Wurfgeschwindigkeit aus linearVelocity berechnen
const getThrowSpeed = (pad) => {
const v = pad?.pose?.linearVelocity;
if (!v) return null;
const [x, y, z] = v;
return Math.hypot(x, y, z); // m/s
};
const pad = navigator.getGamepads().find((p) => p?.pose);
const speed = pad ? getThrowSpeed(pad) : null;
console.log(speed !== null ? `Geschwindigkeit: ${speed.toFixed(2)} m/s` : 'Keine Geschwindigkeitsdaten');
// Wichtig · Fallstricke
Veraltet und nicht standardisiert: GamepadPose gehört zu den WebVR-Erweiterungen der Gamepad API. Nur Firefox hat es umgesetzt, und das auch nur hinter dem Flag dom.gamepad.extensions.enabled. Chrome, Safari und Edge unterstützen es nicht. Für den Produktiveinsatz sollte man es nicht verwenden, sondern auf WebXR (XRInputSource, XRFrame.getPose()) umsteigen.
- Vor dem Zugriff immer prüfen, ob
gamepad.poseexistiert, und die Vektor-Eigenschaften einzeln aufnulltesten. hasPosition === falseheißt: Das Gerät ist ein 3DoF-Controller,positionist dannnulloder geschätzt.- Die zurückgegebenen
Float32Array-Objekte sind Momentaufnahmen. Wer sie speichert, muss sie kopieren (Float32Array.from()), weil manche Implementierungen die Arrays wiederverwenden. - Die Gamepad API setzt einen sicheren Kontext (HTTPS) voraus. Außerdem liefert
navigator.getGamepads()erst Daten, nachdem der Nutzer mit dem Gerät interagiert hat.