In the specification of DeviceOrientation Event, it was mentioned that:
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).
Unfortunately, when iOS 4.2 added the support for this event, the value of
alpha was rather arbitrary. It was consistent, but it bears no relation to the actual magnetic north. Though I did create a compass demo utilizing that event (check it out at ariya.github.com/device/compass), I never get to popularize it because of the drawback referred in its commit log (that’s why hitherto I kept calling it as a “fake compass”):
commit 4b97a9e07e67fff3a2ca38c177bae1c32ea6c209 Author: Ariya Hidayat <ariya .email@example.com> Date: Fri Dec 10 18:53:29 2010 -0800 js/compass: Using device orientation to show rotating compass. Unfortunately, iOS 4.2 does not align the alpha value of the orientation to the real magnetic North. The icon is from http://www.openclipart.org/detail/50329 </ariya>
Fortunately, the excellent browser in Nokia N950 and N9 (read my review) has a faithful implementation of this device orientation event (mostly likely through the Qt Mobility module). Thus, a little fix on the example means that the demo works fine on these two phones. There are some issues I can’t resolve with respect to the actual accuracy, but nothing this app can do about it (since it just visualizes the data sent by the browser).
The code is likely easier to get from the usual X2 git repo (or the alternative repo), look under
How about iOS 5? James demonstrated the use of the new
webkitCompassHeading property for a compass. Based on this, I also updated my own compass example so now it works correctly on iOS 5 and still falls to the fake behavior when running on the older iOS (special thanks to Jay for getting the iOS screenshot).
Also notable here is the same CSS animation trick so that the rotation itself is smooth. Now, for a rotation, north presents a problem since the value wraps around if the needle passes it from west to east and vice versa (imagine 357, 358, 359, and then 0 degrees). Rather than turning off the animation, I used another trick. Instead of setting the absolute direction, the target property value of the CSS animation is actually relative to the current one, this works because the rotation angle in the CSS transformation will be internally reduced to the range of a full circle.
This compass example also support offline mode (via application cache). Thus, if you are iOS 5 or N950/N9 users and in the need of a compass, no need to install an app from the store. Go to ariya.github.com/device/compass, bookmark it, and enjoy!