This is an experimental technology
Check the Browser compatibility table carefully before using this in production.
Increasingly, web-enabled devices are capable of determining their orientation; that is, they can report data indicating changes to their orientation with relation to the pull of gravity. In particular, hand-held devices such as mobile phones can use this information to automatically rotate the display to remain upright, presenting a wide-screen view of the web content when the device is rotated so that its width is greater than its height.
There are two JavaScript events that handle orientation information. The first one is the DeviceOrientationEvent
, which is sent when the accelerometer detects a change to the orientation of the device. By receiving and processing the data reported by these orientation events, it's possible to interactively respond to rotation and elevation changes caused by the user moving the device.
The second event is the DeviceMotionEvent
, which is sent when a change in acceleration was added. It is different from the DeviceOrientationEvent
because it is listening for changes in acceleration as opposed to orientation. Sensors that are commonly capable of detecting DeviceMotionEvent
include sensors in laptops to protect moving storage devices. DeviceOrientationEvent
is more commonly found in mobile devices.
Processing orientation events
All you need to do in order to begin receiving orientation change is to listen to the deviceorientation
event:
Note: gyronorm.js is a polyfill for normalizing the accelerometer and gyroscope data on mobile devices. This is useful for overcoming some of the differences in device support for device orientation.
window.addEventListener("deviceorientation", handleOrientation, true);
After registering your event listener (in this case, a JavaScript function called handleOrientation()), your listener function periodically gets called with updated orientation data.
The orientation event contains four values:
DeviceOrientationEvent.absolute
DeviceOrientationEvent.alpha
DeviceOrientationEvent.beta
DeviceOrientationEvent.gamma
The event handler function can look something like this:
function handleOrientation(event) { var absolute = event.absolute; var alpha = event.alpha; var beta = event.beta; var gamma = event.gamma; // Do stuff with the new orientation data }
Orientation values explained
The value reported for each axis indicates the amount of rotation around a given axis in reference to a standard coordinate frame. These are described in greater detail in the Orientation and motion data explained article which is summarized below.
- The
DeviceOrientationEvent.alpha
value represents the motion of the device around the z axis, represented in degrees with values ranging from 0 to 360. - The
DeviceOrientationEvent.beta
value represents the motion of the device around the x axis, represented in degrees with values ranging from -180 to 180. This represents a front to back motion of the device. - The
DeviceOrientationEvent.gamma
value represents the motion of the device around the y axis, represented in degrees with values ranging from -90 to 90. This represents a left to right motion of the device.
Orientation example
This example will work on any browser supporting the deviceorientation
event and running on a device able to detect its orientation.
So let's imagine a ball in a garden:
<div class="garden"> <div class="ball"></div> </div> <pre class="output"></pre>
This garden is 200 pixel wide (Yes, it's a tiny one), and the ball is in the center:
.garden { position: relative; width : 200px; height: 200px; border: 5px solid #CCC; border-radius: 10px; } .ball { position: absolute; top : 90px; left : 90px; width : 20px; height: 20px; background: green; border-radius: 100%; }
Now, if we move our device, the ball will move accordingly:
var ball = document.querySelector('.ball'); var garden = document.querySelector('.garden'); var output = document.querySelector('.output'); var maxX = garden.clientWidth - ball.clientWidth; var maxY = garden.clientHeight - ball.clientHeight; function handleOrientation(event) { var x = event.beta; // In degree in the range [-180,180] var y = event.gamma; // In degree in the range [-90,90] output.innerHTML = "beta : " + x + "\n"; output.innerHTML += "gamma: " + y + "\n"; // Because we don't want to have the device upside down // We constrain the x value to the range [-90,90] if (x > 90) { x = 90}; if (x < -90) { x = -90}; // To make computation easier we shift the range of // x and y to [0,180] x += 90; y += 90; // 10 is half the size of the ball // It center the positioning point to the center of the ball ball.style.top = (maxY*y/180 - 10) + "px"; ball.style.left = (maxX*x/180 - 10) + "px"; } window.addEventListener('deviceorientation', handleOrientation);
Click here to open this example in a new window; because deviceorientation
doesn't work in a cross-origin <iframe>
in all browsers.
Warning: Chrome and Firefox do not handle the angles the same way, so on some axes the direction are reversed.
Processing motion events
Motion events are handled the same way as the orientation events except that they have their own event's name: devicemotion
window.addEventListener("devicemotion", handleMotion, true);
What's really changed are the information provided within the DeviceMotionEvent
object passed as a parameter of the HandleMotion function.
The motion event contains four properties:
DeviceMotionEvent.acceleration
DeviceMotionEvent.accelerationIncludingGravity
DeviceMotionEvent.rotationRate
DeviceMotionEvent.interval
Motion values explained
The DeviceMotionEvent
objects provide web developers with information about the speed of changes for the device's position and orientation. The changes are provided along three axis (see Orientation and motion data explained for details).
For acceleration
and accelerationIncludingGravity
, those axes correspond to the following:
x
: Represents the axis from West to Easty
: Represents the axis from South to Northz
: Represents the axis perpendicular to the ground
For rotationRate
, the situation is a bit different; the information corresponds to the following in each case:
alpha
: Represents a rotation rate along the axis perpendicular to the screen (or keyboard for desktop).beta
: Represents a rotation rate along the axis going from left to right of the plane of the screen (or keyboard for desktop).gamma
: Represents a rotation rate along the axis going from bottom to top of the plane of the screen (or keyboard for desktop).
Finally, interval
represents the interval of time, in milliseconds, at which data are obtained from the device.
Specifications
Specification | Status | Comment |
---|---|---|
DeviceOrientation Event Specification | Editor's Draft | Initial specification. |
Browser compatibility
DeviceMotionEvent
Desktop | Mobile | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
DeviceMotionEvent | Chrome Full support 11 | Edge Full support ≤18 | Firefox Full support 6 | IE No support No | Opera Full support 15 | Safari Full support 5 | WebView Android Full support ≤37 | Chrome Android Full support 18 | Firefox Android Full support 6 | Opera Android Full support 14 | Safari iOS Full support 4.2 | Samsung Internet Android Full support 1.0 |
DeviceMotionEvent() constructor | Chrome Full support 59 | Edge Full support ≤79 | Firefox ? | IE No support No | Opera ? | Safari ? | WebView Android Full support 59 | Chrome Android Full support 59 | Firefox Android ? | Opera Android ? | Safari iOS ? | Samsung Internet Android Full support 7.0 |
acceleration | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android ? | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
accelerationIncludingGravity | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android Full support Yes | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
interval | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android Full support Yes | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
rotationRate | Chrome Full support Yes | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android Full support Yes | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
Legend
- Full support
- Full support
- No support
- No support
- Compatibility unknown
- Compatibility unknown
- Experimental. Expect behavior to change in the future.
- Experimental. Expect behavior to change in the future.
- Non-standard. Expect poor cross-browser support.
- Non-standard. Expect poor cross-browser support.
DeviceOrientationEvent
Desktop | Mobile | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
DeviceOrientationEvent | Chrome
Full support
7
| Edge Full support ≤18 | Firefox
Full support
6
| IE No support No | Opera Full support 15 | Safari Full support 5 | WebView Android
Full support
≤37
| Chrome Android
Full support
18
| Firefox Android
Full support
6
| Opera Android Full support 14 | Safari iOS Full support 4.2 | Samsung Internet Android
Full support
1.0
|
DeviceOrientationEvent() constructor | Chrome Full support 59 | Edge Full support ≤79 | Firefox ? | IE No support No | Opera ? | Safari ? | WebView Android Full support 59 | Chrome Android Full support 59 | Firefox Android ? | Opera Android ? | Safari iOS ? | Samsung Internet Android Full support 7.0 |
absolute | Chrome Full support 7 | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android Full support Yes | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
alpha | Chrome Full support 7 | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android Full support Yes | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
beta | Chrome Full support 7 | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android Full support Yes | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
gamma | Chrome Full support 7 | Edge Full support 12 | Firefox Full support 6 | IE No support No | Opera Full support Yes | Safari ? | WebView Android Full support Yes | Chrome Android Full support Yes | Firefox Android Full support 6 | Opera Android Full support Yes | Safari iOS Full support 4.2 | Samsung Internet Android Full support Yes |
Legend
- Full support
- Full support
- No support
- No support
- Compatibility unknown
- Compatibility unknown
- Experimental. Expect behavior to change in the future.
- Experimental. Expect behavior to change in the future.
- Non-standard. Expect poor cross-browser support.
- Non-standard. Expect poor cross-browser support.
- See implementation notes.
- See implementation notes.