Sencha Touch + DeviceMotion APIs (= a small plastic toy)

Here at Sencha Towers, we’ve been having a bunch of fun with the new accelerometer & gyroscope APIs in the iOS4.2 web browser.

Rob Dougan has put together a tilt-controlled list and Ariya Hidayat a box of marbles. Both require an updated iPhone or iPod Touch (although Ariya’s also works on a MacBook Pro if you use the Chrome browser).

The APIs are pretty easy to use, and seem to follow the W3C (draft) standards.

I thought I would have a go to, and so I wrote a small Sencha Touch app that mimics one of those small sliding puzzles we all had as kids – but where the tiles are moved not with touch gestures, but by sliding the pieces under gravity.

From a Sencha Touch point of view, I’ve tried to use a best-practice application structure, and both the grid and the tiles are Ext.Panels (which makes them easy to treat in an object-oriented way and, in the case of the tiles, instantiate arbitrarily).

I have set up Ext.EventManager listeners for devicemotion and deviceorientation events, and fortunately, the callback can access the underlying browser event to get the motion-based properties I need.

The tiles themselves are placed on the grid using CSS transforms, rather than top/left positioning, along the lines of:

Ext.Element.cssTransform(this.getEl(), {translate: [x, y]});

This makes coding the sliding movement unbelievably easy: I simply have to change the transformation to where I want the tile to move to, and then

-webkit-transition:-webkit-transform .8s ease-in;

does the gentle slide. Wow. Transitions and transforms have been a spectacular epiphany for me in the last few months.

One catch with web-based tilt control: tip the device more than 45 degrees, and you might find yourself switching between portrait and landscape mode. I don’t know of a way to disable this in Mobile Safari.

The issue with this is that the co-ordinate system of the device’s physical orientation does not rotate, but the web page does. So in my case, I check the window’s current rotation and subtract the appropriate multiple of 90 degrees so that the elements still slide in the direction expected for the device’s physical position.

To test it out, get an iPhone or iPod Touch with iOS4.2 installed. Put the device level on a horizontal surface, go to – then tilt the device about 15 degrees in various directions to make the tiles slide.

Also feel free to look at (and be tempted to improve!) the code. Small, simple, and good fun: let me know what you think.