Copyright © 2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C liability, trademark and document use rules apply.
This specification defines several new DOM events that provide information about the physical orientation and motion of a hosting device.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the Geolocation Working Group. If you wish to make comments regarding this document, please send them to public-geolocation@w3.org (subscribe, archives).
All feedback is welcome.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This is the First Public Working draft of this specification. It should not be considered stable. When providing feedback, please first refer to the Editor's Draft and confirm that the issue has not been addressed already. If the issue has not been addressed, please describe it on the public mailing list.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
All diagrams, examples, and notes in this specification are non-normative, as are all sections explicitly marked non-normative. Everything else in this specification is normative.
The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this document are to be interpreted as described in RFC2119. For readability, these words do not appear in all uppercase letters in this specification. [RFC2119]
Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.
Conformance requirements phrased as algorithms or specific steps may be implemented in any manner, so long as the end result is equivalent. (In particular, the algorithms defined in this specification are intended to be easy to follow, and not intended to be performant.)
User agents may impose implementation-specific limits on otherwise unconstrained inputs, e.g. to prevent denial of service attacks, to guard against running out of memory, or to work around platform-specific limitations.
Implementations that use ECMAScript to implement the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification, as this specification uses that specification's terminology. [WEBIDL]
The events introduced by this specification implement the Event interface defined in the DOM4 Specification, [DOM4]. Implementations must therefore support this specification.
This section is non-normative.
This specification provides several new DOM events for obtaining information about the physical orientation and movement of the hosting device. The information provided by the events is not raw sensor data, but rather high-level data which is agnostic to the underlying source of information. Common sources of information include gyroscopes, compasses and accelerometers.
The first DOM event provided by the specification,
deviceorientation
, supplies the physical orientation of the
device, expressed as a series of rotations from a local coordinate frame.
The second DOM event provided by this specification,
devicemotion
, supplies the acceleration of the device, expressed
in Cartesian coordinates in a coordinate frame defined in the device.
It also supplies the rotation rate of the device about a local coordinate
frame. Where practically possible, the event should provide the acceleration
of the device's center of mass.
Finally, the specification provides a compassneedscalibration
DOM event, which is used to inform Web sites that a compass being used to
provide data for one of the above events is in need of calibration.
The following code extracts illustrate basic use of the events.
Registering to receive
deviceorientation
events:
window.addEventListener("deviceorientation", function(event) { // process event.alpha, event.beta and event.gamma }, true);
A device lying flat on a horizontal surface with the top of the screen pointing West has the following orientation:
{alpha: 90, beta: 0, gamma: 0};
To get the compass heading, one would simply
subtract alpha
from 360 degrees. As the device is
turned on the horizontal surface, the compass heading is (360
- alpha
).
A user is holding the device in their hand, with the screen in
a vertical plane and the top of the screen pointing upwards. The
value of beta
is 90, irrespective of
what alpha
and gamma
are.
A user facing a compass heading of alpha degrees is holding the device in their hand, with the screen in a vertical plane and the top of the screen pointing to their right. The orientation of the device is:
{alpha: 270 - alpha, beta: 0, gamma: 90};
Showing custom UI to instruct the user to calibrate the compass:
window.addEventListener("compassneedscalibration", function(event) { alert('Your compass needs calibrating! Wave your device in a figure-eight motion'); event.preventDefault(); }, true);
Registering to receive
devicemotion
events:
window.addEventListener("devicemotion", function(event) { // Process event.acceleration, event.accelerationIncludingGravity, // event.rotationRate and event.interval }, true);
A device lying flat on a horizontal surface with the screen upmost has
an acceleration
of zero and the following value for
accelerationIncludingGravity
:
{x: 0, y: 0, z: 9.81};
A device in free-fall, with the screen horizontal and upmost, has an
accelerationIncludingGravity
of zero and the following value
for acceleration
:
{x: 0, y: 0, z: -9.81};
A device is mounted in a vehicle, with the screen in a vertical plane,
the top uppermost and facing the rear of the vehicle. The vehicle is
travelling at speed v around a right-hand bend of radius r. The
device records a positive x component for both acceleration
and accelerationIncludingGravity
. The device also records a
negative value for rotationRate.gamma
:
{acceleration: {x: v^2/r, y: 0, z: 0}, accelerationIncludingGravity: {x: v^2/r, y: 0, z: 9.81}, rotationRate: {alpha: 0, beta: 0, gamma: -v/r*180/pi} };
This section is non-normative.
This specification is limited to providing DOM events for retrieving information describing the physical orientation and motion of the hosting device. The intended purpose of this API is to enable simple use cases such as those in Section 5.2. The scope of this specification does not include providing utilities to manipulate this data, such as transformation libraries. Nor does it include providing access to low sensor data, or direct control of these sensors.
User agents implementing this specification must provide a new DOM event,
named deviceorientation
. The corresponding event must be of
type DeviceOrientationEvent
and must fire on the
window
object. Registration for, and firing of the
deviceorientation
event must follow the usual behavior of DOM4 Events,
[DOM4].
User agents must also provide an event handler IDL attribute
[HTML5] named ondeviceorientation
on the
window
object. The type of the corresponding event must be
deviceorientation
.
[Constructor(DOMString type, optional DeviceOrientationEventInit eventInitDict)] interface DeviceOrientationEvent : Event { readonly attribute double? alpha; readonly attribute double? beta; readonly attribute double? gamma; readonly attribute boolean absolute; } dictionary DeviceOrientationEventInit : EventInit { double? alpha; double? beta; double? gamma; boolean absolute; }
The alpha
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to null.
The beta
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to null.
The gamma
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to null.
The absolute
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to false.
The event should fire whenever a significant change in orientation occurs. The definition of a significant change in this context is left to the implementation, though a maximum threshold for change of one degree is recommended. Implementations may also fire the event if they have reason to believe that the page does not have sufficiently fresh data.
The alpha
, beta
and gamma
attributes
of the event must specify the orientation of the device in terms of the
transformation from a coordinate frame fixed on the Earth to a
coordinate frame fixed in the device. The coordinate frames must be oriented
as described below.
The Earth coordinate frame is a 'East, North, Up' frame at the user's location. It has the following 3 axes, where the ground plane is tangent to the spheriod of the World Geodetic System 1984 [WGS84], at the user's location.
For a mobile device such as a phone or tablet, the device coordinate frame
is defined relative to the screen in its standard orientation, typically
portrait. This means that slide-out elements such as keyboards are not
deployed, and swiveling elements such as displays are folded to their default
position. If the
orientation of the screen changes when the device is rotated or a slide-out
keyboard is deployed, this does not affect the orientation of the coordinate
frame relative to the device. Users wishing to detect these changes in screen
orientation may be able to do so with the existing
orientationchange
event.
For a laptop computer, the device coordinate frame is defined relative to the
integrated keyboard.
The transformation from the Earth coordinate frame to the device coordinate frame must use the following system of rotations.
Rotations must use the right-hand convention, such that positive rotation around an axis is clockwise when viewed along the positive direction of the axis. Starting with the two frames aligned, the rotations are applied in the following order:
Rotate the device frame around its z axis by alpha
degrees, with alpha
in [0, 360).
Rotate the device frame around its x axis by beta
degrees, with beta
in [-180, 180).
Rotate the device frame around its y axis by gamma
degrees, with gamma
in [-90, 90).
Thus the angles alpha
, beta
and
gamma
form a set of intrinsic Tait-Bryan angles of type Z-X'-Y''.
[EULERANGLES]
Note that this choice of angles follows mathematical convention, but means
that alpha
is in the opposite sense to a compass heading. It also
means that the angles do not match the roll-pitch-yaw convention used in
vehicle dynamics.
Implementations that are unable to provide absolute values for the three
angles may instead provide values relative to some arbitrary orientation, as
this may still be of utility. In this case, the absolute
property
must be set to false
. Otherwise, the absolute
property must be set to true
.
Implementations that are unable to provide all three angles must
set the values of the unknown angles to null. If any angles are provided, the
absolute
property must be set appropriately. If an implementation
can never provide orientation information, the event should be fired
with all properties set to null.
User agents implementing this specification must provide a new DOM event,
named compassneedscalibration
that uses the Event
interface defined in the DOM4 Events specification
[DOM4]. This event must fire on the
window
object. Registration for, and firing of the
compassneedscalibration
event must follow the usual behavior of
DOM4 Events [DOM4].
User agents must also provide an event handler IDL attribute
[HTML5] named oncompassneedscalibration
on the window
object. The type of the corresponding event must be
compassneedscalibration
.
This event must be fired when the user agent determines that a compass used
to obtain orientation data is in need of calibration. Furthermore, user agents
should only fire the event if calibrating the compass will increase the
accuracy of the data provided by the
deviceorientation
event.
The default action of this event should be for the user agent to present the user with details of how to calibrate the compass. The event must be cancelable, so that web sites can provide their own alternative calibration UI.
User agents implementing this specification must provide a new DOM event,
named devicemotion
. The corresponding event must be of type
DeviceMotionEvent
and must fire on the window
object.
Registration for, and firing of the devicemotion
event must follow the usual behavior of DOM4 Events,
[DOM4].
User agents must also provide an event handler IDL attribute
[HTML5] named ondevicemotion
on the window
object. The type of the corresponding event must be
devicemotion
.
[Callback, NoInterfaceObject] interface DeviceAcceleration { readonly attribute double? x; readonly attribute double? y; readonly attribute double? z; } [Callback, NoInterfaceObject] interface DeviceRotationRate { readonly attribute double? alpha; readonly attribute double? beta; readonly attribute double? gamma; } [Constructor(DOMString type, optional DeviceMotionEventInit eventInitDict)] interface DeviceMotionEvent : Event { readonly attribute DeviceAcceleration? acceleration; readonly attribute DeviceAcceleration? accelerationIncludingGravity; readonly attribute DeviceRotationRate? rotationRate; readonly attribute double? interval; } dictionary DeviceMotionEventInit : EventInit { DeviceAcceleration? acceleration; DeviceAcceleration? accelerationIncludingGravity; DeviceRotationRate? rotationRate; double? interval; }
The acceleration
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to null.
The accelerationIncludingGravity
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to null.
The rotationRate
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to null.
The interval
attribute must return the value it was initialized to.
When the object is created, this attribute must be initialized to 0.
In the DeviceMotionEvent
events fired by the user agent, the following requirements
must apply:
The acceleration
attribute must be initialized with the acceleration of the
hosting device relative to the Earth frame, expressed in the body frame, as
defined in section 4.1. The acceleration must
be expressed in meters per second squared (m/s2).
Implementations that are unable to provide acceleration data without the
effect of gravity (due, for example, to the lack of a gyroscope) may instead
supply the acceleration including the effect of gravity. This is less useful
in many applications but is provided as a means of providing best-effort
support. In this case, the accelerationIncludingGravity
attribute
must be initialized with the acceleration of the hosting device, plus an acceleration
equal and opposite to the acceleration due to gravity. Again, the acceleration
must be given in the body frame defined in
section 4.1 and must be expressed in meters per second squared (m/s2).
The rotationRate
attribute must be initialized with the rate of rotation of
the hosting device in space. It must be expressed as the rate of change of
the angles defined in section 4.1 and
must be expressed in degrees per second (deg/s).
The interval
attribute must be initialized with the interval at which
data is obtained from the underlying hardware and must be expressed in
milliseconds (ms). It must be a constant, to simplify filtering of the data by the
Web application.
Implementations that are unable to provide all attributes must initialize the values of the unknown attributes to null. If an implementation can never provide motion information, the event should be fired with all attributes set to null.
A gaming Web application monitors the device's orientation and interprets tilting in a certain direction as a means to control an on-screen sprite.
A Web application monitors the device's acceleration and applies signal processing in order to recognize certain specific gestures. For example, using a shaking gesture to clear a web form.
A mapping Web application uses the device's orientation to correctly align the map with reality.
This section is non-normative.
The following worked example is intended as an aid to users of the DeviceOrientation event.
Section 2 provided an example of using the DeviceOrientation event to obtain a compass heading when the device is held with the screen horizontal. This example shows how to determine the compass heading that the user is 'facing' when holding the device with the screen approximately vertical in front of them. An application of this is an augmented-reality system.
More precisely, we wish to determine the compass heading of the horizontal component of a vector which is orthogonal to the device's screen and pointing out of the back of the screen.
If v represents this vector in the rotated device body frame xyz, then v is as follows.
The transformation of v due to the rotation about the z axis can be represented by the following rotation matrix.
The transformation of v due to the rotation about the x axis can be represented by the following rotation matrix.
The transformation of v due to the rotation about the y axis can be represented by the following rotation matrix.
If R represents the full rotation matrix of the device in the earth frame XYZ, then since the initial body frame is aligned with the earth, R is as follows.
If v' represents the vector v in the earth frame XYZ, then since the initial body frame is aligned with the earth, v' is as follows.
The compass heading θ is given by
provided that β and γ are not both zero.
The compass heading calculation above can be represented in JavaScript as follows to return the correct compass heading when the provided parameters are defined, not null and represent absolute
values.
var degtorad = Math.PI / 180; // Degree-to-Radian conversion function compassHeading( alpha, beta, gamma ) { var _x = beta ? beta * degtorad : 0; // beta value var _y = gamma ? gamma * degtorad : 0; // gamma value var _z = alpha ? alpha * degtorad : 0; // alpha value var cX = Math.cos( _x ); var cY = Math.cos( _y ); var cZ = Math.cos( _z ); var sX = Math.sin( _x ); var sY = Math.sin( _y ); var sZ = Math.sin( _z ); // Calculate Vx and Vy components var Vx = - cZ * sY - sZ * sX * cY; var Vy = - sZ * sY + cZ * sX * cY; // Calculate compass heading var compassHeading = Math.atan( Vx / Vy ); // Convert compass heading to use whole unit circle if( Vy < 0 ) { compassHeading += Math.PI; } else if( Vx < 0 ) { compassHeading += 2 * Math.PI; } return compassHeading * ( 180 / Math.PI ); // Compass Heading (in degrees) }
As a consistency check, if we set γ = 0, then
as expected.
Alternatively, if we set β = 90, then
as expected.
This section is non-normative.
Describing orientation using Tait-Bryan angles can have some disadvantages such as introducing gimbal lock [GIMBALLOCK]. Depending on the intended application it can be useful to convert the Device Orientation values to other rotation representations.
The first alternate orientation representation uses rotation matrices. By combining the component rotation matrices provided in the worked example above we can represent the orientation of the device body frame as a combined rotation matrix.
If R represents the rotation matrix of the device in the earth frame XYZ, then since the initial body frame is aligned with the earth, R is as follows.
The above combined rotation matrix can be represented in JavaScript as follows provided passed parameters are defined, not null and represent absolute
values.
var degtorad = Math.PI / 180; // Degree-to-Radian conversion function getRotationMatrix( alpha, beta, gamma ) { var _x = beta ? beta * degtorad : 0; // beta value var _y = gamma ? gamma * degtorad : 0; // gamma value var _z = alpha ? alpha * degtorad : 0; // alpha value var cX = Math.cos( _x ); var cY = Math.cos( _y ); var cZ = Math.cos( _z ); var sX = Math.sin( _x ); var sY = Math.sin( _y ); var sZ = Math.sin( _z ); // // ZXY rotation matrix construction. // var m11 = cZ * cY - sZ * sX * sY; var m12 = - cX * sZ; var m13 = cY * sZ * sX + cZ * sY; var m21 = cY * sZ + cZ * sX * sY; var m22 = cZ * cX; var m23 = sZ * sY - cZ * cY * sX; var m31 = - cX * sY; var m32 = sX; var m33 = cX * cY; return [ m11, m12, m13, m21, m22, m23, m31, m32, m33 ]; };
Another alternate representation of device orientation data is as Quaternions. [QUATERNIONS]
If q represents the unit quaternion of the device in the earth frame XYZ, then since the initial body frame is aligned with the earth, q is as follows.
The above quaternion can be represented in JavaScript as follows provided the passed parameters are defined, are absolute
values and those parameters are not null.
var degtorad = Math.PI / 180; // Degree-to-Radian conversion function getQuaternion( alpha, beta, gamma ) { var _x = beta ? beta * degtorad : 0; // beta value var _y = gamma ? gamma * degtorad : 0; // gamma value var _z = alpha ? alpha * degtorad : 0; // alpha value var cX = Math.cos( _x/2 ); var cY = Math.cos( _y/2 ); var cZ = Math.cos( _z/2 ); var sX = Math.sin( _x/2 ); var sY = Math.sin( _y/2 ); var sZ = Math.sin( _z/2 ); // // ZXY quaternion construction. // var w = cX * cY * cZ - sX * sY * sZ; var x = sX * cY * cZ - cX * sY * sZ; var y = cX * sY * cZ + sX * cY * sZ; var z = cX * cY * sZ + sX * sY * cZ; return [ w, x, y, z ]; }
We can check that a Unit Quaternion has been constructed correctly using Lagrange's four-square theorem
as expected.
This section is non-normative.
It may be necessary for applications to compensate for screen orientation changes to ensure that the device coordinate frame continues to match the current screen orientation as expected - defined as the screen-adjusted device orientation frame.
This specification defines its coordinate frame as relative to the screen in its default body frame orientation. When screen orientation changes, from e.g. portrait to landscape or vice-versa, the device coordinate frame and thus, data returned from Device Orientation events, remains unchanged.
Typical screen orientation changes can be represented by, but may not be limited to, the following screen rotations around a device body frame's z axis from the default screen orientation in the default body frame:
0
degree rotation around the body frame's z axis. This is the default screen orientation of the device.90
degree rotation clockwise around the body frame's z axis.180
degree rotation clockwise around the body frame's z axis.270
degree rotation clockwise around the body frame's z axis.We can obtain and record the current orientation of the screen around a device body frame's z axis via the Screen Orientation API [SCREENORIENTATION] as follows:
var screenOrientation = window.screen.orientation.angle || 0; window.addEventListener("orientationchange", function() { screenOrientation = window.screen.orientation.angle || 0; }, false);
If an application requires its coordinate frame to reflect the way the screen is currently oriented on the device then a screen-adjusted device orientation frame can be calculated by re-assigning x-, y- and z-axis outputs from Device Orientation events.
When working directly with Tait-Bryan angles provided from the Device Orientation event then the re-mapping of α, β and γ device orientation values as follows:
Current Screen Orientation (clockwise rotation from default screen orientation) |
Tait-Bryan axis rotation re-assignment | ||
---|---|---|---|
x | y | z | |
0 | beta (β) | gamma (γ) | alpha (α) |
90 | - gamma (-γ) | beta (β) | alpha (α) |
180 | - beta (-β) | - gamma (-γ) | alpha (α) |
270 | gamma (γ) | - beta (-β) | alpha (α) |
The table above is included for reference purposes only.
It is strongly recommended that developers employ one of the documented alternate device orientation representations to
account for screen orientation changes instead of attempting to directly re-map Tait-Bryan angles and axis'. Use of alternate device orientation representations is recommended due to the non-linear relationship between individual Tait-Bryan angles and their respective axis' and to avoid subsequent issues introduced when applying incompatible linear rotation values to different axis'.
When representing device orientation as a rotation matrix (R) provided in the previous worked example then a screen orientation angle transformation should be applied to the previously calculated rotation matrix representation (R) to obtain a screen-adjusted rotation matrix that matches the current device frame (Rs).
If the current screen orientation value is denoted by θ then our screen-adjusted rotation matrix Rs can be calculated as
where rs is the following z axis based transformation matrix
This calculation of Rs can be represented in JavaScript as follows:
function getScreenAdjustedRotationMatrix( alpha, beta, gamma, screenOrientation ) { // Get the standard device rotation matrix var R = getRotationMatrix( alpha, beta, gamma ); var orientationAngle = screenOrientation ? screenOrientation * degtorad : 0; var cA = Math.cos( orientationAngle ); var sA = Math.sin( orientationAngle ); // Construct a screen transformation matrix var r_s = [ cA, -sA, 0, sA, cA, 0, 0, 0, 1 ]; // // Multiply the device rotation matrix by the screen rotation matrix: // // R_s = R * r_s // // and return a screen-adjusted rotation matrix in the form: // // [m11, m12, m13, m21, m22, m23, m31, m32, m33] // return multiplyMatrixes( R, r_s ); // matrix multiplication is out of scope }
Similarly, when representing device orientation as a quaternion (q) as also provided in the previous worked example then a screen orientation angle transformation should be applied to the previously calculated quaternion representation (q) to obtain a screen-adjusted quaternion that matches the current device frame (q's).
If the current screen orientation value is denoted by θ then our screen-adjusted quaternion q's can be calculated as
where qs is the following z axis based transformation quaternion
This calculation of q's can be represented in JavaScript as follows:
function getScreenAdjustedQuaternion( alpha, beta, gamma, screenOrientation ) { // Get the standard device rotation quaternion var Q = getQuaternion( alpha, beta, gamma ); var orientationAngle = screenOrientation ? screenOrientation * degtorad : 0; var minusHalfAngle = - orientationAngle / 2; // Construct the screen transformation quaternion var q_s = [ Math.cos( minusHalfAngle ), 0, 0, Math.sin( minusHalfAngle ) ]; // // Multiply the device rotation quaternion by the screen transformation quaternion: // // Q_s = Q * q_s // // and return a screen-adjusted unit quaternion in the form: // // [w, x, y, z] // return multiplyQuaternions( Q, q_s ); // quaternion multiplication is out of scope }
Lars Erik Bolstad, Dean Jackson, Claes Nilsson, George Percivall, Doug Turner, Matt Womer