150

I have recently come across a few websites that seems to access the accelerometer or gyroscope on my laptop, detecting changes in orientation or movement.

How is this done? Must I subscribe to some kind of event on the window object?

On which devices (laptops, mobile phones, tablets) is this known to work?


NB: I actually already know (part of) the answer to this question, and I am going to post it right away. The reason that I am posting the question here, is to let everyone else know that accelerometer data is available in Javascript (on certain devices) and to challenge the community to post new findings on the subject. Currently, there seems to be almost no documentation of these features.

Jørn Schou-Rode
  • 37,718
  • 15
  • 88
  • 122
  • Great effort, thanks a lot. Do you think that 3 years later the answer needs any updates? – Bartek Banachewicz Jan 17 '14 at 17:12
  • @BartekBanachewicz Thanks for calling me out on this one. I will transfer the answer to "community wiki", hoping that someone with more up-to-date knowledge will update it to reflect the current state of the art. – Jørn Schou-Rode Jan 27 '14 at 14:43
  • I couldn't find if this operation requires user consent. I didn't want to make a new question since it fits perfectly with your question. Maybe we can add this here? Does anyone know if this require explicit consent? Is this the case in all browsers and all mobile OSes? – Silver Nov 24 '16 at 13:32

4 Answers4

185

There are currently three distinct events which may or may not be triggered when the client devices moves. Two of them are focused around orientation and the last on motion:

  • ondeviceorientation is known to work on the desktop version of Chrome, and most Apple laptops seems to have the hardware required for this to work. It also works on Mobile Safari on the iPhone 4 with iOS 4.2. In the event handler function, you can access alpha, beta, gamma values on the event data supplied as the only argument to the function.

  • onmozorientation is supported on Firefox 3.6 and newer. Again, this is known to work on most Apple laptops, but might work on Windows or Linux machines with accelerometer as well. In the event handler function, look for x, y, z fields on the event data supplied as first argument.

  • ondevicemotion is known to work on iPhone 3GS + 4 and iPad (both with iOS 4.2), and provides data related to the current acceleration of the client device. The event data passed to the handler function has acceleration and accelerationIncludingGravity, which both have three fields for each axis: x, y, z

The "earthquake detecting" sample website uses a series of if statements to figure out which event to attach to (in a somewhat prioritized order) and passes the data received to a common tilt function:

if (window.DeviceOrientationEvent) {
    window.addEventListener("deviceorientation", function () {
        tilt([event.beta, event.gamma]);
    }, true);
} else if (window.DeviceMotionEvent) {
    window.addEventListener('devicemotion', function () {
        tilt([event.acceleration.x * 2, event.acceleration.y * 2]);
    }, true);
} else {
    window.addEventListener("MozOrientation", function () {
        tilt([orientation.x * 50, orientation.y * 50]);
    }, true);
}

The constant factors 2 and 50 are used to "align" the readings from the two latter events with those from the first, but these are by no means precise representations. For this simple "toy" project it works just fine, but if you need to use the data for something slightly more serious, you will have to get familiar with the units of the values provided in the different events and treat them with respect :)

Jørn Schou-Rode
  • 37,718
  • 15
  • 88
  • 122
  • 10
    sometimes an answer just nails it ! – Scott Evernden Sep 11 '11 at 16:58
  • 1
    In case anybody wonders - ondevicemotion works for Firefox 8.0 but is scaled wrongly (0-9), but this seems to be fixed in later versions (10.0). None of them works on Opera Mobile and all standard ones work fine on default Nokia N9 browser. – Nux Dec 08 '11 at 20:40
  • 2
    The MozOrientation event was removed as obsolete in Firefox 6. So now they're all using the standardised API. – Chris Morgan Aug 10 '12 at 04:05
  • This doesn't seem to work in Firefox 30, as shown in [this fiddle](http://jsfiddle.net/Tb5f8/5/). :( – bwinton Mar 22 '14 at 15:28
  • sidenote: [Plax.js](http://cameronmcefee.com/plax/), which is used in github's 404 and 500 pages, [uses ondeviceorientation](https://github.com/cameronmcefee/plax/blob/master/js/plax.js#L334). – Yosh Sep 29 '14 at 06:47
23

Can't add a comment to the excellent explanation in the other post but wanted to mention that a great documentation source can be found here.

It is enough to register an event function for accelerometer like so:

if(window.DeviceMotionEvent){
  window.addEventListener("devicemotion", motion, false);
}else{
  console.log("DeviceMotionEvent is not supported");
}

with the handler:

function motion(event){
  console.log("Accelerometer: "
    + event.accelerationIncludingGravity.x + ", "
    + event.accelerationIncludingGravity.y + ", "
    + event.accelerationIncludingGravity.z
  );
}

And for magnetometer a following event handler has to be registered:

if(window.DeviceOrientationEvent){
  window.addEventListener("deviceorientation", orientation, false);
}else{
  console.log("DeviceOrientationEvent is not supported");
}

with a handler:

function orientation(event){
  console.log("Magnetometer: "
    + event.alpha + ", "
    + event.beta + ", "
    + event.gamma
  );
}

There are also fields specified in the motion event for a gyroscope but that does not seem to be universally supported (e.g. it didn't work on a Samsung Galaxy Note).

There is a simple working code on GitHub

Matt
  • 179
  • 7
18

The way to do this in 2019+ is to use DeviceOrientation API. This works in most modern browsers on desktop and mobile.

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
}
str
  • 42,689
  • 17
  • 109
  • 127
1

Usefull fallback here: https://developer.mozilla.org/en-US/docs/Web/Events/MozOrientation

function orientationhandler(evt){


  // For FF3.6+
  if (!evt.gamma && !evt.beta) {
    evt.gamma = -(evt.x * (180 / Math.PI));
    evt.beta = -(evt.y * (180 / Math.PI));
  }

  // use evt.gamma, evt.beta, and evt.alpha 
  // according to dev.w3.org/geo/api/spec-source-orientation


}

window.addEventListener('deviceorientation',  orientationhandler, false);
window.addEventListener('MozOrientation',     orientationhandler, false);
Luckylooke
  • 4,061
  • 4
  • 36
  • 49