Device Motion
This controller listens to devicemotion events from the Device Motion API and emits a normalized updated event containing acceleration, acceleration including gravity, rotation rate, and sampling interval. It also manages the permission flow when required.
Usage
<div {{ stimulus_controller('@pwa/device-motion') }}>
  <p id="motion-status">Waiting for motion data…</p>
</div>
<script type="module">
  const host = document.querySelector('[data-controller="pwa__device-motion"]');
  const out = document.getElementById('motion-status');
  host.addEventListener('device-motion:unavailable', () => {
    out.textContent = 'Device Motion API is not available on this device/browser.';
  });
  host.addEventListener('device-motion:permission-granted', () => {
    out.textContent = 'Permission granted. Receiving motion data…';
  });
  host.addEventListener('device-motion:permission-denied', () => {
    out.textContent = 'Permission denied. Cannot access motion sensors.';
  });
  host.addEventListener('device-motion:updated', (e) => {
    const { acceleration, rotationRate, interval } = e.detail;
    out.textContent =
      `Acc: x=${acceleration.x?.toFixed(2)} y=${acceleration.y?.toFixed(2)} z=${acceleration.z?.toFixed(2)} | ` +
      `Rot: α=${rotationRate.alpha?.toFixed(1)} β=${rotationRate.beta?.toFixed(1)} γ=${rotationRate.gamma?.toFixed(1)} | ` +
      `dt=${interval}ms`;
  });
</script>Parameters
throttleValue: Intended to control how often updated events are dispatched to avoid spamming the UI.
Actions
None
Targets
None
Events
unavailable: the feature is not supported by the device.
permission-granted: permission prompt was granted; listener is attached.
permission-denied: User denied permission, or an error occurred during the permission request.
updated: On every device motion event (as delivered by the browser).
Contains the following object:
{
  acceleration: {
    x: number | null,
    y: number | null,
    z: number | null
  },
  accelerationIncludingGravity: {
    x: number | null,
    y: number | null,
    z: number | null
  },
  rotationRate: {
    alpha: number | null, // deg/s around Z
    beta: number | null,  // deg/s around X
    gamma: number | null  // deg/s around Y
  },
  interval: number // ms between samples
}Last updated
Was this helpful?