HTML5 Rocks

Show navigation Table of Contents

Table of Contents

Localizations:

This End Up: Using Device Orientation

HTML5 Rocks

Pete LePage

Published: April 29th, 2011 Comments: 0
Your browser may not support the functionality in this article.

Introduction

Many new computers, mobile phones and other devices are now shipping standard with accelerometers, gyroscopes, compasses and other hardware designed to determine capture motion and orientation data. At the same time, web browsers are providing increasingly more access to that new hardware. One example of that are the new HTML5 DeviceOrientation and DeviceMotion events. These events provide developers with information about the orientation, motion and acceleration of the device.

Today, all modern mobile browsers support device orientation, and most support device motion, with Chrome for Android and Opera being the holdouts. Thankfully they're working on it and we should see it soon. Note, if you need to support older versions of Firefox, it has an implementation using a slightly different event model.

These events have a lot of fun uses, such as using orientation to control the direction of character in a game, or motion to determine how high a character should jump. Additionally, you can use these events beyond gaming. When used with GeoLocation, you can create a more accurate turn-by-turn navigation system.

In this article, we’ll take a look at the two different events, and use CSS to rotate an image based on the orientation of the device.

Which end is up?

There are a couple of things that we need to make sure we understand before we can start using these events, which end is up and what are the axes we’re going to use?

Device Orientation Data

To answer this question, we need to align our device with the local earth frame. To do that, take your device, and put it on flat, level surface with the top of the device pointing directly north. To do this with a phone, turn around until you are facing north, and place the phone on a flat table, with the bottom of the phone closest to you and the top pointed north. For a laptop, the situation is similar, except the screen is open at a 90° angle, facing you and the keyboard in-line with the surface.

Phone is in its normal position, on a flat on a surface, with the screen facing up, the top of the phone pointed directly north and the bottom of the phone is closest to you. The X, Y and Z values increase as you move to the right, forward or up respectively.

Device Motion Data

Acceleration data is returned as a coordinate frame with three axes, x, y and z. The x-axis runs side-to-side across the mobile phone screen, or the laptop keyboard and is positive towards the right side. The y-axis runs front-to-back across the mobile phone screen or the laptop keyboard and is positive towards as it moves away from you. The z-axis comes straight up out of the mobile phone screen or the laptop keyboard and is positive as it moves up.

The phone is rotated on the Y-Axis by gamma degrees.

The rotation data uses Euler angles to represent the difference between the device in it’s normal position and it’s current position. With the HTML5 device orientation events, the data is returned as the number of degrees different from normal. An easier way to think about it is how much the device is tilted front-to-back, is referred to as beta. How much its tilted side-to-side, is known as gamma. And finally how much has it been rotated around the z-axis, is known as alpha.

One thing to keep in mind is that most people don’t use their phones when they’re in this flat position, and instead have rotated them around the x-axis so the screen is facing them, this will affect the acceleration data that is returned from the device motion events.

Differences in Browsers

As mentioned earlier, alpha, beta and gamma are determined based on the position the device is with the local earth frame. For most browsers, alpha returns the compass heading, so when the device is pointed north, alpha is zero. With Mobile Safari, alpha is based on the direction the device was pointing when device orientation was first requested. The compass heading is available in the webkitCompassHeading parameter.

The events

Device orientation

The device orientation event returns only the rotation data, which includes how much the device is leaning front-to-back (beta), side-to-side (gamma) and if the phone or laptop has a compass, the direction the device is facing (alpha).

Let’s see a couple examples:

You are looking down at a phone that is lying on a flat, horizontal surface, with north at the top of the frame.
{evt.alpha: 0, evt.beta: 0, evt.gamma: 0} 
You are looking down at a phone that is lying on a flat, horizontal surface, with north at the top of the frame. The phone has been rotated by 180° so it is pointing south.
{evt.alpha: 180, evt.beta: 0, evt.gamma: 0} 
You are looking down at a device that does not have a compass built in, it is pointed west and tilted up by 45° with the left side of the phone higer than the right.
{evt.alpha: null, evt.beta: 0, evt.gamma: 45} 
You are looking down at a phone that is pointed north and tilted up by 45° with the top of the phone higer than the bottom.
{evt.alpha: 0, evt.beta: 45, evt.gamma: 0}

Device motion

The device motion event is a superset of the device orientation event; it returns data about the rotation information and alsoacceleration information about the device. The acceleration data is returned in three axes: x, y and z. They are measured inmeters per second squared (m/s^2). Because some devices might not have the hardware to exclude the effect of gravity, the event returns two properties, accelerationIncludingGravity and acceleration, which excludes the effects of gravity, (when this is the case, the acceleration data will be null).

A laptop in its normal position, with the screen facing up, the data returned would be:
Not accelerating Accelerating up Accelerating forward Accelerating right Accelerating up & to the right

acceleration {0, 0, 0} {0, 0, 5} {0, 2, 0} {3, 0, 0} {5, 0, 5}
accelerationIncludingGravity {0, 0, 9.81} {0, 0, 14.81} {0, 2, 9.81} {3, 0, 9.81} {5, 0, 14.81}

A mobile phone rotated along the x-axis so the screen is perpendicular to it’s normal position would return:
Not accelerating Accelerating up Accelerating forward Accelerating right Accelerating up & to the right

acceleration {0, 0, 0} {0, 5, 0} {0, 0, 2} {3, 0, 0} {5, 5, 0}
accelerationIncludingGravity {0, 9.81, 0} {0, 14.81, 0} {0, 9.81, 2} {3, 9.81, 0} {5, 14.81, 0}

Using the DeviceOrientation events

1. Check for compatibility

Check to see if DeviceOrientationEvent supported.

if (window.DeviceOrientationEvent) {
console.log("DeviceOrientation is supported");
}

One thing to note, some devices (for example, the original iPad) say that they support the event when in fact they don’t. In these cases, the event is fired only once, and all of the properties are null.

2. Declare the markup

For this example, we’re going to display the orientation data and then apply that information as a CSS3 transform to an image.

<div class="main">
<h2>Device Orientation</h2>
<table>
<tr>
<td>Event Supported</td>
<td id="doEvent"></td>
</tr>
<tr>
<td>Tilt Left/Right [gamma]</td>
<td id="doTiltLR"></td>
</tr>
<tr>
<td>Tilt Front/Back [beta]</td>
<td id="doTiltFB"></td>
</tr>
<tr>
<td>Direction [alpha]</td>
<td id="doDirection"></td>
</tr>
</table>
</div> <div class="container" >
<img src="html5_logo.png" id="imgLogo" class="logo">
</div>

3. Add an event listener

Now that we know what events are supported, add the appropriate event listeners:

if (window.DeviceOrientationEvent) {
// Listen for the event and handle DeviceOrientationEvent object
window.addEventListener('deviceorientation', devOrientHandler, false);
}

4. Handle the event

The HTML5 DeviceOrientation event returns three pieces of data:

  • alpha the direction the device is facing according to the compass
  • beta the angle in degrees the device is tilted front-to-back
  • gamma the angle in degrees the device is tilted left-to-right.

The angles values increase as you tilt the device to the right or towards you.

if (window.DeviceOrientationEvent) {
document.getElementById("doEvent").innerHTML = "DeviceOrientation";
// Listen for the deviceorientation event and handle the raw data
window.addEventListener('deviceorientation', function(eventData) {
// gamma is the left-to-right tilt in degrees, where right is positive
var tiltLR = eventData.gamma; // beta is the front-to-back tilt in degrees, where front is positive
var tiltFB = eventData.beta; // alpha is the compass direction the device is facing in degrees
var dir = eventData.alpha // call our orientation event handler
deviceOrientationHandler(tiltLR, tiltFB, dir);
}, false);
} else {
document.getElementById("doEvent").innerHTML = "Not supported."
}

5. Respond to the data

We’ll display it in the table we created in step 2, and also add rotate the image using a CSS3 transform.

document.getElementById("doTiltLR").innerHTML = Math.round(tiltLR);
document.getElementById("doTiltFB").innerHTML = Math.round(tiltFB);
document.getElementById("doDirection").innerHTML = Math.round(dir); // Apply the transform to the image
var logo = document.getElementById("imgLogo");
logo.style.webkitTransform =
"rotate("+ tiltLR +"deg) rotate3d(1,0,0, "+ (tiltFB*-1)+"deg)";
logo.style.MozTransform = "rotate("+ tiltLR +"deg)";
logo.style.transform =
"rotate("+ tiltLR +"deg) rotate3d(1,0,0, "+ (tiltFB*-1)+"deg)";

The final product

Try it out, and view the source to see it in action.

Using the DeviceMotion events

The DeviceMotionEvent provides the acceleration and rotation data of the device. In our example, we’re going to use accelerationIncludingGravity to determine the orientation of the device and get a similar result to the sample we built with DeviceOrientation.

1. Check for compatibility

First thing we want to do is determine if the DeviceMotionEvent is supported using feature detection.

if (window.DeviceMotionEvent) {
console.log("DeviceMotionEvent supported");
}

Like DeviceOrientationEvent, if a browser cannot provide motion information, the event will be fired once and all properties will be null.

2. Add an event listener

Now that we know that the browser and device supports the DeviceMotionEvent, we can add an event listener.

if ((window.DeviceMotionEvent) {
window.addEventListener('devicemotion', deviceMotionHandler, false);
} else {
document.getElementById("dmEvent").innerHTML = "Not supported."
}

3. Declare the markup

For this example, we’re just going to display data that we receive.

<div class="main">
<h2>Device Motion</h2>
<table>
<tr>
<td>Event Supported</td>
<td id="dmEvent"></td>
</tr>
<tr>
<td>acceleration</td>
<td id="moAccel"></td>
</tr>
<tr>
<td>accelerationIncludingGravity</td>
<td id="moAccelGrav"></td>
</tr>
<tr>
<td>rotationRate</td>
<td id="moRotation"></td>
</tr>
<tr>
<td>interval</td>
<td id="moInterval"></td>
</tr>
</table>
</div>

4. Create an event handler

We want to display the raw data that we get back.

function deviceMotionHandler(eventData) {
var info, xyz = "[X, Y, Z]"; // Grab the acceleration from the results
var acceleration = eventData.acceleration;
info = xyz.replace("X", acceleration.x);
info = info.replace("Y", acceleration.y);
info = info.replace("Z", acceleration.z);
document.getElementById("moAccel").innerHTML = info; // Grab the acceleration including gravity from the results
acceleration = eventData.accelerationIncludingGravity;
info = xyz.replace("X", acceleration.x);
info = info.replace("Y", acceleration.y);
info = info.replace("Z", acceleration.z);
document.getElementById("moAccelGrav").innerHTML = info; // Grab the rotation rate from the results
var rotation = eventData.rotationRate;
info = xyz.replace("X", rotation.alpha);
info = info.replace("Y", rotation.beta);
info = info.replace("Z", rotation.gamma);
document.getElementById("moRotation").innerHTML = info; // // Grab the refresh interval from the results
info = eventData.interval;
document.getElementById("moInterval").innerHTML = info;
}

The final product

When you load the page and move the device around, you should see the values change as the device moves through space and is affected by acceleration.

Try it out, and view the source to see it in action.

Additional resources

Here are a few other resources and demos you can check out that use the HTML5 device orientation or device motion events.

Physics

The Specs

Neat Demos

Pong An experiment to try out device orientation in gaming.

Comments

Please enable JavaScript to view the comments powered by Disqus.

Next steps

Share

Twitter Facebook Google+

Subscribe

Enjoyed this article? Grab the RSS feed and stay up-to-date.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the Apache 2.0 License.

[HTML5]如何使用移动设备的方向定位器的更多相关文章

  1. ios获取设备手持方向——电子罗盘

    转:http://book.51cto.com/art/201411/457105.htm 2014-11-15 19:07 张亚飞/崔巍 中国铁道出版社 字号:T | T 综合评级: 想读()  在 ...

  2. 获取Android设备的方向,Sensor和SensorManager实现手机旋转角度

    http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1009/425.html 带有g-sensor的Android设备上可通过API ...

  3. 基于HTML5的Web跨设备超声波通信方案

    前言:Chirp在iPhone上掀起了有声传输文件的序幕,我们再也不需要彩信.蓝牙配对.IM来传送数据.它通过“叽叽喳喳”的小鸟叫声来分享数据,简单有趣,而且可以快速的实现一对多的分享. 此外支付宝曾 ...

  4. 基于HTML5 的WebSql本地设备数据库

    HTML5 的 Web SQL Database 用本地和会话存储实现简单的对象持久化,对繁琐的关系数据进行处理. 在 W3C 的 Web SQL Database 规范中(参照 介绍)有这样的描述: ...

  5. HTML5开发之获取设备的地理坐标

    近期一段时间開始学一下html5,发现里面有好多的知识还是蛮新颖的.所以整理了一下自己练习过的demo给大家分享下,以下的代码是通过js接口获取当前的地理坐标. <!doctype html&g ...

  6. IT兄弟连 HTML5教程 在移动设备上设置原始大小显示

    在iPhone系列和iPod Touch中使用的是Safari浏览器,它支持前面介绍的媒体查询表达式.例如,使用iPhone 320px×480px的分辨率去访问我们前面的布局示例,却无法得到我们想看 ...

  7. [device-orientation] 使用手机设备的方向感应实现图片选择

    <div class="main"> <h2>Device Orientation</h2> <table> <tbody&g ...

  8. JS侦测设备旋转方向

    window.onload = window.onresize = function initialLoad(){updateOrientation();} function updateOrient ...

  9. javascript检查移动设备是否支持重力方向感应

    javascript如何检查移动设备,如手机平台是否支持重力或者方向感应. 可以使用html5提供的重力和方向感应接口来判断. html5 中针对高端手机提供了重力感应和重力加速的接口,开发可以利用这 ...

随机推荐

  1. linux系统web站点设置-http基础设置

    一.httpd2.2的组成: /etc/httpd:服务器的根目录 conf/httpd.conf,conf.d/*:配置文件 conf/magic:MIME的配置文件 logs:日志文件的存放路径, ...

  2. JavaScript调用wcf服务,并且处理返回的字典集合

    1.第一步创建wcf服务的方法 using System;using System.Collections.Generic;using System.Linq;using System.Runtime ...

  3. 字符串匹配 - sunday算法

    常见的字符串匹配算法有BF.KMP(教科书中非常经典的).BM.Sunday算法 这里主要想介绍下性能比较好并且实现比较简单的Sunday算法 . 基本原理: 从前往后匹配,如果遇到不匹配情况判断母串 ...

  4. Bootstrap学习遇到的role属性--- 无障碍网页应用属性

    以前接触过Bootstrap,但也只是仅仅接触,现在重新学习下,今天看到一个例子中的属性有一个role, 查阅资料发现这个是--WAI-ARIA无障碍设计属性: 通俗说是该设计为了一些盲人,失聪,残疾 ...

  5. 使用UIkit的uk-form-icon后input框无法输入的问题

    相关版本UIkit2.27.5 uikit.min.css默认使用uk-form-icon的属性pointer-events: none:因此表框无法点击. <style type=text/c ...

  6. SpringBoot 多环境配置

    转载:https://www.cnblogs.com/gdpuzxs/p/7191436.html 在我们的实际开发中,一般都有三套环境,开发环境,测试环境,生产环境,三套环境的数据库连接配置也有所不 ...

  7. floor函数

    C++中 可以用floor函数来截断小数部分 floor(x)返回一个不大于x的整数,有点像取整函数

  8. 2019.01.20 bzoj3999: [TJOI2015]旅游(树链剖分)

    传送门 树链剖分菜题. 题意不清差评. 题意简述(保证清晰):给一棵带权的树,每次从aaa走到bbb,在走过的路径上任意找两个点,求后访问的点与先访问的点点权差的最大值. 思路: 考虑暴力:维护路径的 ...

  9. Codeforces Round #517 (Div. 2) C. Cram Time(思维+贪心)

    https://codeforces.com/contest/1065 题意 给你a,b,让你找尽量多的自然数,使得他们的和<=a,<=b,用在a和b的自然数不能重复 思路 假如只有一个数 ...

  10. Linq高级应用

    Linq的应用为我们带来了很大的方便,提高了coding效率,最近看到了一个用linq写的数独游戏算法,让我看到了Linq写的是如此优雅,耳目一新的感觉,以前没有写过这样的代码,同时也感觉到原来Lin ...