Understanding How the Accelerometer and Gyroscope Work in the Browser

Link to Final Product

I’ll be covering the basics of accessing the accelerometer and gyroscope with JavaScript in the post below. We’ll discuss the difference between the two technologies and write a simple example to log out information when the device has detected a change in orientation. To simplify DOM manipulation, the code will depend on either Zepto or jQuery (I highly recommend Zepto when working in mobile).

In iOS 4.0 and above, Apple has allowed the web browser (via JavaScript) to access data returned from both the accelerometer and gyroscope. Supported devices include (only if the operating system is 4.0 or greater):

  • Accelerometer – iPhone 4, iPad, iPad2, iPod Touch
  • Gyroscope – iPhone 4, iPad2, iPod Touch

Unfortunately, Android devices do not currently support the use of the accelerometer or gyroscope in the web browser. You’ll have to stick to the rudimentary ‘onorientationchange’ event. If you’d like to read more about this event, the Safari Developer Library has several good explanations.

What’s the Difference between the Accelerometer and the Gyroscope?

Measurements

The accelerometer measures foce in the X, Y, and Z dimensions. Think of holding the device directly in front of you… moving the device vertically in space changes the y value, horizontally changes x, and moving the device towards and away from you changes the z value.

The gyroscope measures orientation in the a, b, and g dimensions. Think of holding the device directly in front of you… moving the device like you would steer a car changes the Alpha value, tilting the device forwards and backwards will effect the Beta value, and twisting the device like you’re opening a soda will change the Gamma value.

Force vs. Orientation

When executing the codeblocks below, you’ll notice that the X, Y, and Z values will read zero, or close to zero, when holding the device motionless. This is because the accelerometer only outputs the force of a a change in orientation, not the orientation itself. Modern browsers also supply the “accelerationincludinggravity” property when emitting the ondevicemotion event which works differently and we will not be using it in this post.

Unlike the accelerometer, all of the channels of the gyroscope will continuously read the orientation of the device, even when motionless. Try moving the phone in space without any twisting force… you’ll notice little to no effect in the gyroscopic values.

The Code

I’m starting with an entirely blank html file. The only things we’ll need to include are a reference to Zepto and a series of DOM elements to hold the textual information we’ll be logging out. You can download the final zip package here.

All I’m doing here is associating DOM elements with JavaScript variables. Nothing special.

1
2
3
4
5
6
var x_dom = $('.x');
var y_dom = $('.y');
var z_dom = $('.z');
var a_dom = $('.a');
var b_dom = $('.b');
var g_dom = $('.g');

Accelerometer – The “ondevicemotion” event is native to browsers that support the accelerometer. We can use this event to constantly track the changes in motion related to the X, Y, and Z dimensions. After collecting the data from the event, we write the information to the DOM.

1
2
3
4
5
6
7
8
window.ondevicemotion = function(event) {
    var x = event.acceleration.x;
    var y = event.acceleration.y;
    var z = event.acceleration.z;
    x_dom.text(x);
    y_dom.text(y);
    z_dom.text(z);
}

Gyroscope – We’re doing the same thing here with the gyroscope. Like the accelerometer, this method is native to devices that support the respective instrument.

1
2
3
4
5
6
7
8
window.ondeviceorientation = function(event) {
    var a = event.alpha;
    var b = event.beta;
    var g = event.gamma;
    a_dom.text(a);
    b_dom.text(b);
    g_dom.text(g);
}

If you log the above code, you’ll notice the instruments are very, very sensitive and the strings returned are somewhat long. Since it’s kind of difficult to look at that kind of information in the DOM, I’ve added a rounding function to display a single whole number. Also, adding a %2B sign to the string makes switches between positive and negative numbers less visually striking.

The Final Product:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
var x_dom = $('.x');
var y_dom = $('.y');
var z_dom = $('.z');
var a_dom = $('.a');
var b_dom = $('.b');
var g_dom = $('.g');
//This is only for devices that support the use of a gyroscope (iPhone 4, iPad2, iPod Touch)  
window.ondeviceorientation = function(event) {
    var a = Math.round(event.alpha*1/1);
    var b = Math.round(event.beta*1/1);
    var g = Math.round(event.gamma*1/1);
    if(a >= ) { a = '%2B' %2B a}
    if(b >= ) { b = '%2B' %2B b}
    if(g >= ) { g = '%2B' %2B g}

    a_dom.text(a);
    b_dom.text(b);
    g_dom.text(g);
}

window.ondevicemotion = function(event) {
    var x = Math.round(event.acceleration.x*1/1);
    var y = Math.round(event.acceleration.y*1/1);
    var z = Math.round(event.acceleration.z*1/1);

    if(x >= ) { x = '%2B' %2B x}
    if(y >= ) { y = '%2B' %2B y}
    if(z >= ) { z = '%2B' %2B z}

    x_dom.text(x);
    y_dom.text(y);
    z_dom.text(z);
}

Finished, not a whole lot to it and pretty easy overall. I’m really looking forward to seeing how people use these new technologies to build web applications. Note: In real life scenarios it’s probably overkill to collect/broadcast information on device motion and orientation change, you’ll want to use some kind of intervalled data collection to prevent the browser from killing itself.

Downloads

Further Reading

Comments