Using a mobile accelerometer to enhance web app UI

A accelerometer is one of the important sensors in mobiles. This sensor along with a gyroscope is essentially used by most mobiles games to detect motion in 3 dimensions whenever a mobile is moved or shaken. Although common with mobiles applications, web applications seldom use the features provided by these sensors. With some ingenuity we can use these sensors to enhance the user experience of a web app on a mobile device without much effort.

There are a few javascript libraries around that will help you detect mobile motion and fire a ‘devicemotion’ event which we can than capture and use in our UI design. In this post we will see a couple of demos using a mobile accelerometer that will fire a event whenever a mobile is shaken.

Our first simple demo is shown below that displays a random a variation on a eCommerce product. This allows a user to see a variation on a product along with the price by shaking the phone. (test on any smart phone)

View Demo

A simple way to include the feature in your mobile app is to add the following javascript:

<script type="text/javascript" src="jquery.min.js"></script>
 
<!-- Shake library - https://github.com/lhagan/jquery.ios-shake -->
<script type="text/javascript" src="jquery.ios-shake.js"></script>
 
<script type="text/javascript">
    $(document).ready(function() {
        $.shake({
            callback: function() {
                yourFunction();
            }
        });
    });
 
    yourFunction() {
        // Do something here on a 'shake'
    }
</script>

The important function here is ‘yourFunction'; you can add any code here that you need to run whenever a phone is shaken. In our demo here we load a variation on a product along with a price. Here we have preloaded the image urls on the page which are randomly shown on a phone shake.

   function changeProduct() {
        var shirts = [
                      ["images/1.jpg","12.65"],
                      ["images/2.jpg","10.00"],
                      ["images/3.jpg","15.50"],
                      ["images/4.jpg","12.65"],
                      ["images/5.jpg","13.00"],
                      ["images/6.jpg","11.85"]
                      ];
 
        var pos = Math.floor((Math.random() * shirts.length) + 0);
        $("#image").html($("<img/>").attr("src", shirts[pos][0]));
        $(".price").html("$" + shirts[pos][1]);
    }
 
    $(document).ready(function() {
        function onShake() {
            changeProduct();
        }
 
        $.shake({
            callback: function() {
                onShake();
            }
        });
    });

The html part of the display is given below.

<div id="content">
        <div id="item">
        <span>Design T-shirts</span>
        <div id="image"><img src="images/1.jpg" /></div>
        <span class="price">$12.65</span>
        </div>
        <h4>Shake phone to change product</h4>
</div>

In another demo we load a random Flickr image whenever a phone is shaken (a little slower as the images are retrieved from Flickr). The complete code for the demo is given below.

function showpics() {
        $.getJSON('http://api.flickr.com/services/feeds/photos_public.gne?tags=nature,water,leaves,trees,flowers&tagmode=any&format=json&jsoncallback=?',
            function(data) { 
                $("#images").hide().html(data).fadeIn('fast');
                var dataLength = data.items.length;
                if(dataLength > 0) {
                    var pos = Math.floor((Math.random() * dataLength) + 1); 
                    $("#image").html($("<img/>").attr("src", data.items[pos].media.m));
                }
            })
        };
 
    $(document).ready(function() {
        function onShake() {
            showpics();
        }
 
        $.shake({
            callback: function() {
                onShake();
            }
        });
    });

To view the complete code you can view the source of the demo page.

Setting options

You can also customize a bit more – you can raise violence to decrease sensitivity or decrease the debounce if you need to detect shakes faster than one per second. The debug and supported options allow you to pass div IDs to ios-shake so that it can place some specific content on your page.

$.shake({
    debug: "#debugdiv",             // debug div id
    supported: "#notsupporteddiv",  // not supported message div
    violence: 3.0,                  // single shake sensitivity
    hf: 0.2,                        // high-pass filter constant
    shakethreshold: 5,              // number of single shakes required to fire a shake event
    debounce: 1000,                 // delay between shake events (in ms)
    callback: function() {
        yourFunction();
    }
});

Checking if device motion is supported

You can check if device motion is supported with the following. The device motion feature should be an addon to the web app rather than the main feature. So even on unsupported devices the web app should function as usual.

if (window.DeviceMotionEvent === undefined) {
    // no supported, so ignore  shake events
}