Signatur
Beschreibung
DeviceMotionEvent gehört zur Spezifikation Device Orientation Events. Es wird als devicemotion-Event in regelmäßigen Abständen am window-Objekt ausgelöst und liefert Messwerte der Bewegungssensoren des Geräts: die lineare Beschleunigung (mit und ohne Erdanziehung) und die Drehrate um die drei Geräteachsen.
Wichtige Eigenschaften:
acceleration– einDeviceMotionEventAcceleration-Objekt mitx,y,zin m/s² ohne Einfluss der Schwerkraft (kannnullsein, wenn das Gerät kein Gyroskop hat).accelerationIncludingGravity– Beschleunigung inklusive Schwerkraft (liegt das Gerät flach, istz≈ 9,81).rotationRate– einDeviceMotionEventRotationRate-Objekt mitalpha,beta,gammain Grad pro Sekunde.interval– Zeitabstand zwischen zwei Messungen in Millisekunden.
Typische Einsatzgebiete sind Schüttelgesten („Shake to undo“), Schrittzähler, Spielsteuerungen, Parallaxeffekte und Augmented-Reality-Anwendungen. Für die reine Ausrichtung des Geräts (Kompass, Neigung) eignet sich dagegen DeviceOrientationEvent besser.
Das Event wird nur in sicheren Kontexten (HTTPS) ausgelöst. Unter iOS Safari muss die Berechtigung zuvor per DeviceMotionEvent.requestPermission() innerhalb einer Nutzerinteraktion (z. B. Klick) eingeholt werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Konstruktor-Parameter: Name des Events, normalerweise "devicemotion". |
|
| $options | { acceleration?: object, accelerationIncludingGravity?: object, rotationRate?: object, interval?: number, bubbles?: boolean, cancelable?: boolean } | {} | Optionales Initialisierungsobjekt für new DeviceMotionEvent(). Beschleunigungen als {x, y, z}, Drehrate als {alpha, beta, gamma}, interval in Millisekunden (Standard 0). |
Rückgabewert
Beispiele
Beschleunigung per addEventListener auslesen
const handleMotion = (event) => {
const { x, y, z } = event.accelerationIncludingGravity ?? {};
const rot = event.rotationRate ?? {};
console.log(`Beschl.: x=${x?.toFixed(2)} y=${y?.toFixed(2)} z=${z?.toFixed(2)} m/s²`);
console.log(`Drehrate: α=${rot.alpha?.toFixed(1)} β=${rot.beta?.toFixed(1)} γ=${rot.gamma?.toFixed(1)} °/s`);
console.log(`Intervall: ${event.interval} ms`);
};
if ('DeviceMotionEvent' in window) {
window.addEventListener('devicemotion', handleMotion);
} else {
console.log('DeviceMotionEvent wird nicht unterstützt.');
}
// Später wieder abmelden, um Akku zu sparen:
// window.removeEventListener('devicemotion', handleMotion);
Berechtigung unter iOS anfordern (Klick erforderlich)
const button = document.querySelector('#sensor-start');
button.addEventListener('click', async () => {
// iOS 13+: requestPermission existiert nur dort
if (typeof DeviceMotionEvent.requestPermission === 'function') {
try {
const state = await DeviceMotionEvent.requestPermission();
if (state !== 'granted') {
console.log('Zugriff auf Bewegungssensoren verweigert.');
return;
}
} catch (err) {
console.error('Berechtigungsabfrage fehlgeschlagen:', err);
return;
}
}
window.ondevicemotion = (e) => {
console.log('z inkl. Schwerkraft:', e.accelerationIncludingGravity?.z);
};
});
Schüttelgeste erkennen mit Drosselung
const SHAKE_THRESHOLD = 15; // m/s²
const COOLDOWN_MS = 1000;
let lastShake = 0;
const onShake = () => console.log('Gerät geschüttelt – Aktion rückgängig machen!');
window.addEventListener('devicemotion', (event) => {
const a = event.acceleration;
if (!a || a.x === null) return; // kein Gyroskop / keine Daten
const magnitude = Math.hypot(a.x, a.y, a.z);
const now = Date.now();
if (magnitude > SHAKE_THRESHOLD && now - lastShake > COOLDOWN_MS) {
lastShake = now;
onShake();
}
});
Synthetisches Event für Tests erzeugen
window.addEventListener('devicemotion', (e) => {
console.log(e.accelerationIncludingGravity.z, e.interval);
});
const fake = new DeviceMotionEvent('devicemotion', {
accelerationIncludingGravity: { x: 0, y: 0, z: 9.81 },
rotationRate: { alpha: 0, beta: 0, gamma: 0 },
interval: 16
});
window.dispatchEvent(fake);
// Wichtig · Fallstricke
- Nur HTTPS: In unsicheren Kontexten (HTTP) wird das Event nicht ausgelöst bzw. ist die Schnittstelle nicht verfügbar.
- iOS Safari: Seit iOS 13 ist
DeviceMotionEvent.requestPermission()Pflicht und darf nur als Reaktion auf eine Nutzergeste aufgerufen werden. Ohne Erlaubnis kommen keine Events an. - Nullwerte:
acceleration,rotationRateund einzelne Achsen könnennullsein, wenn die Hardware fehlt (z. B. Desktop-Rechner). Immer defensiv prüfen. - Achsen und Ausrichtung: Die Achsen beziehen sich auf das Gerät, nicht auf den Bildschirm. Bei Drehung ins Querformat vertauschen sich x und y aus Sicht des Nutzers – ggf. mit
screen.orientation.angleumrechnen. Einige ältere Android-Browser lieferten invertierte Vorzeichen. - Performance/Akku: Das Event feuert sehr häufig (oft 60 Hz). Aufwendige Arbeit im Handler vermeiden, per
requestAnimationFramebündeln und den Listener entfernen, wenn er nicht gebraucht wird. - Datenschutz: Bewegungsdaten eignen sich für Fingerprinting und können Rückschlüsse auf Eingaben zulassen. Browser drosseln daher die Genauigkeit oder verlangen Berechtigungen; per
Permissions-Policy: accelerometer, gyroscopelässt sich der Zugriff in iframes steuern. - Die moderne Alternative ist die Generic Sensor API (
Accelerometer,Gyroscope), die allerdings nur in Chromium-Browsern verfügbar ist.