# useDeviceOrientation

The device's orientation from its motion sensors: compass direction (`alpha`) and tilt (`beta`, `gamma`), updated as it moves.

On iOS the user must allow motion access, and the request only works from a tap: until then `needsPermission` is `true`, so show a button that calls `requestPermission()`. Browsers that don't require it (Chrome, Firefox) send readings right away, and `needsPermission` turns `false` on the first one. Laptops and desktops usually have no sensor, so `orientation` stays `null`. Re-renders on every reading, up to about 60 times a second.

## Import

```ts
import { useDeviceOrientation } from '@vincent.ri/react-tils'
// or only this hook
import { useDeviceOrientation } from '@vincent.ri/react-tils/useDeviceOrientation'
```

## Usage

```ts
const { orientation, needsPermission, requestPermission } = useDeviceOrientation()
if (needsPermission) return <button onClick={requestPermission}>Enable tilt</button>
const tilt = orientation?.gamma ?? 0
return <div style={{ transform: `rotate(${tilt}deg)` }}>🧭</div>
```

## When to use it

Tilt effects, a compass, steering in a game, or a "level" tool.

## When not to

You only need portrait or landscape; use `useMediaQuery('(orientation: portrait)')`. For the user's position, use `useGeolocation`.

## API

```ts
function useDeviceOrientation(): DeviceOrientationState
```

**Returns** `{ orientation, needsPermission, requestPermission }`.

### Types

```ts
export type Orientation = {
  /** Compass direction around the vertical axis, 0 to 360 degrees. */
  alpha: number | null;
  /** Front-to-back tilt, -180 to 180 degrees. */
  beta: number | null;
  /** Left-to-right tilt, -90 to 90 degrees. */
  gamma: number | null;
};
export type DeviceOrientationState = {
  /** The latest reading, or `null` before the first one (and always on devices without the sensor). */
  orientation: Orientation | null;
  /** `true` while the browser may need permission and no reading has arrived (iOS until granted): show a button that calls `requestPermission`. */
  needsPermission: boolean;
  /** Ask for motion access on iOS. Must be called from a tap or click. Resolves to whether it was granted. */
  requestPermission: () => Promise<boolean>;
};
```

## Browser support

Works in all modern browsers.

- iOS needs `requestPermission()` called from a tap. Desktops usually have no sensor, so `orientation` stays `null`.

## Coming from another library?

Other libraries call this `useOrientation` (react-use), `useDeviceMotion`, `useGyroscope`.

---

331 B minified and brotlied
Source: https://github.com/vincentri/react-tils/blob/main/src/useDeviceOrientation.ts
Docs page: https://vincentri.github.io/react-tils/hooks/useDeviceOrientation/
Previous: [usePageRestore](https://vincentri.github.io/react-tils/hooks/usePageRestore.md)
Next: [useEventListener](https://vincentri.github.io/react-tils/hooks/useEventListener.md)
