Home > HTML 5, Programming > HTML5 and iOS device orientation

HTML5 and iOS device orientation

Whether orientation is scary or exciting, you usually have to go.

If you’ve spent any time with an iOS device like an iPhone, you’ve discovered that one of the coolest behaviors of the device is that it responds to how you are holding it.  If you hold it vertically, the screen orients itself in portrait mode, and if you hold it horizontally, the screen rotates to landscape mode.  For various reasons, many native apps lock this behavior down so that the screen does not orient no matter how the user turns the device. Examples include the home screen on the iPhone itself (though not the iPad) or many native games where the the UI has been carefully crafted for a specific screen shape.  Some native apps, however, do adjust their interface and behavior depending on how the user is holding the device.  The humble iPhone calculator is a great example of this type of app behavior (if you haven’t noticed, try launching the calculator while holding your iPhone vertically, then watch what happens when you turn the iPhone horizontal).  As an HTML5 developer probably knows, Safari is another app that reacts to the orientation of the device, by default rotating the web page it is pointed to so that the display is always pointed “up” and adjusting the zoom level of the screen to the new aspect ratio.

First the good news

For HTML5 developers writing apps on top of mobile Safari, I have good news and bad news.  In the good news department, somewhat to my surprise, Apple grants your HTML5 app access to the current orientation of the device.  This allows me to build an app that can determine whether the device is in portrait or landscape mode before I draw to the canvas and render a different UI depending on the which mode the device is currently in.  See?

Landscape mode is red!

Portrait mode is blue!

You can get at this information in a couple of different ways.  You can query the current orientation of the device by reading

window.orientation

which will return an integer value of either 0, 90, or -90 (in number form, not a string or object) depending on how the user is holding the device. In theory, iPhone may return a value of 180 someday as well, as the iPad does today, but in practice a value of 180 is not supported on the iPhone in iOS5.

Alternatively, you can register a callback function which will provide direct access to the device’s accelerometer values:

window.ondevicemotion = function(event) {
  x = event.accelerationIncludingGravity.x
  y = event.accelerationIncludingGravity.y
  z = event.accelerationIncludingGravity.z
};

If you register a callback function, you get much more fine-tuned information about how the user is holding their device, but be ready for a lot of callback events, similar to the deluge of data you get with touchmove callbacks.

But there’s some bad news

So that’s the good news: your application or game can be aware of the device’s orientation, even at the HTML5 layer!  Here’s the bad news: your application or game MUST be aware of the device’s orientation.  Yes, I’m afraid if your HTML5 app is using a full-screen canvas to render your UI within the canvas element, you can’t really get away with ignoring the orientation of the device.  Here’s why: unlike a native application, an HTML5 application can’t stop Safari from responding to the orientation of the device.  If the user turns their device from portrait to landscape mode or vice versa, Safari will run its little rotation animation and the screen will rotate in response to the new orientation.  It is up to your application how to behave in response to this behavior, but if you do nothing, your canvas element that fit so well at 320×460 will no longer match the screen’s new dimensions of at 480×300.  This behavior takes place whether your app is running in standalone mode or embedded within the full Safari UI. (Standalone mode was discussed more in the previous post.)

Don't let the Dark Side dominate your destiny. It does terrible things to your family relations.

It gets worse.  A simple rotation of your UI in response to the orientation changing–in effect, trying to “undo” the rotation so your UI is constant no matter the orientation of the device–is not sufficient.  There are two problems in trying to take the relatively easy way out (otherwise known, as Master Yoda tells us, as the Dark Side of the Force).

First, Safari is going to do that rotation animation whether you like it or not.  If you re-orient your UI back to its original position on the physical device after it has rotated, to the user it will look like the screen has rotated one way then “snapped” back to where it was.  It looks bad, trust me, I tried it.

Second, when the screen rotates, it’s not just a matter of swapping the X and Y values to pretend it didn’t happen, because those don’t take into account the additional iPhone UI elements your HTML5 app is operating within which _will_ rotate along with the device.  In standalone mode, you have the 20 pixel header bar which moves from the top of the vertical screen to the top of the horizontal screen. This is why the dimensions of a standalone app in portrait mode are 320×460 but in landscape mode become 480×300.  When operating with the Safari bar on the bottom of the screen, it just gets worse.

Trust your feelings

What to do instead?  Embrace the Light Side!  Having an app that gives the user a different UI depending on whether they’re holding the iPhone in portrait or landscape mode is really cool.  It’s a mode we as developers haven’t begun to properly explore yet, and it’s high time we’ve started to.  How fortunate we are as HTML5 developers to have access to this information! We should use it and write our applications to leverage it.  Your users will think it’s the coolest thing ever and love using your app on their phone.

There you have it. Orientation on the iPhone in HTML5.  Learn it, love it.  You kind of have to.  And let me know what you build with it!

Good luck!

Advertisements
Categories: HTML 5, Programming Tags: , , ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: