Reading device motion and orientation
Modern mobile devices ship with accelerometers, gyroscopes, and often a compass. Browsers expose these sensors through deviceorientation and devicemotion events, which you can use to react to how a device is tilted, rotated, or moved. Typical use cases range from shake gestures and parallax effects to games and turn-by-turn navigation when combined with geolocation.
Coordinate frames and rotation values
The data returned by these events is only meaningful if you understand the two coordinate systems involved. The Earth coordinate frame uses X, Y, and Z and is aligned with gravity and standard magnetic orientation.
| Coordinate system | |
|---|---|
X |
Represents the east-west direction (where east is positive). |
Y |
Represents the north-south direction (where north is positive). |
Z |
Represents the up-down direction, perpendicular to the ground (where up is positive). |
The device coordinate frame uses lowercase x, y, and z and is centered on the device itself.
| Coordinate system | |
|---|---|
X |
In the plane of the screen, positive to the right. |
Y |
In the plane of the screen, positive towards the top. |
Z |
Perpendicular to the screen or keyboard, positive extending away. |
For phones and tablets, orientation is defined relative to portrait mode. For desktops and laptops, the reference is the keyboard.
Rotation is reported as Euler angles, measured in degrees, representing the difference between the device frame and the Earth frame:
alpha: Rotation around the z axis. It is 0° when the top of the device points north and increases as the device rotates counter-clockwise.beta: Rotation around the x axis. It is 0° when the top and bottom of the device are equidistant from the ground and increases as the top is tipped toward the earth's surface.gamma: Rotation around the y axis. It is 0° when the left and right edges are equidistant from the ground and increases as the right side is tipped downward.
Handling device orientation events
The deviceorientation event provides rotation data describing how far the device leans front-to-back and side-to-side. If the device has a compass, it also reports the facing direction via alpha; on Mobile Safari, an additional webkitCompassHeading parameter is available.
Which events you choose should match your use case. Orientation events are useful for subtle UI effects like parallax, map rotation as the user turns, or navigation assistance. Do not overuse them: test for support before attaching listeners, and never update the UI directly on every event. Instead, schedule visual updates with requestAnimationFrame.
Listening for orientation support
To use the API, first verify the browser supports DeviceOrientationEvent, then attach a listener for the deviceorientation event on the window object.
if (window.DeviceOrientationEvent) {
window.addEventListener('deviceorientation', deviceOrientationHandler, false);
document.getElementById('doeSupported').innerText = 'Supported!';
}
Handling device motion events
While orientation events describe static tilt, the devicemotion event reports movement at a regular interval. It provides rotationRate in degrees per second and acceleration values in m/sec2. The acceleration property excludes the effect of gravity, while accelerationIncludingGravity includes it. The fourth property, interval, indicates the time between events.
Note that not all devices have the hardware to separate gravity from acceleration. And as with orientation, be mindful of differences in browser implementations.
Common applications for device motion
- Shake gestures to refresh content.
- Controls in games, such as making a character jump.
- Health and fitness tracking apps.
Listening for motion support
Mirroring the pattern for orientation, check for DeviceMotionEvent support first, then register a listener for devicemotion on window.
if (window.DeviceMotionEvent) {
window.addEventListener('devicemotion', deviceMotionHandler);
setTimeout(stopJump, 3 * 1000);
}
Interpreting acceleration values
To illustrate the difference between the two acceleration properties, imagine a phone lying flat on a table with the screen facing up. The gravity-excluded acceleration will read near zero, while accelerationIncludingGravity will show approximately 9.81 m/sec2 on the z axis.
| State | Rotation | Acceleration (m/s2) | Acceleration with gravity (m/s2) |
|---|---|---|---|
| Not moving | [0, 0, 0] | [0, 0, 0] | [0, 0, 9.8] |
| Moving up towards the sky | [0, 0, 0] | [0, 0, 5] | [0, 0, 14.81] |
| Moving only to the right | [0, 0, 0] | [3, 0, 0] | [3, 0, 9.81] |
| Moving up and to the right | [0, 0, 0] | [5, 0, 5] | [5, 0, 14.81] |
If the same phone is held perpendicular to the ground, directly in front of the viewer, the gravity effect shifts. The accelerationIncludingGravity value now appears along the y axis, and in some cases may also appear as a negative z value.
| State | Rotation | Acceleration (m/s2) | Acceleration with gravity (m/s2) |
|---|---|---|---|
| Not moving | [0, 0, 0] | [0, 0, 0] | [0, 9.81, 0] |
| Moving up towards the sky | [0, 0, 0] | [0, 5, 0] | [0, 14.81, 0] |
| Moving only to the right | [0, 0, 0] | [3, 0, 0] | [3, 9.81, 0] |
| Moving up and to the right | [0, 0, 0] | [5, 5, 0] | [5, 14.81, 0] |
Calculating maximum acceleration
One useful pattern is tracking extreme values during a short interval. The following example measures the maximum acceleration experienced during a jump by comparing values before and after the user taps a button.
if (evt.acceleration.x > jumpMax.x) {
jumpMax.x = evt.acceleration.x;
}
if (evt.acceleration.y > jumpMax.y) {
jumpMax.y = evt.acceleration.y;
}
if (evt.acceleration.z > jumpMax.z) {
jumpMax.z = evt.acceleration.z;
}
The page instructs the user to jump after they tap the button, stores the maximum and minimum acceleration values during the event stream, and reports the result once the motion has settled.



