本文档旨在通过介绍HTML5 DeviceOrientation 和DeviceMotion两个接口的使用,来实现某些场景应用,如
- 摇一摇功能(DeviceMotion)
- 重力感应方向控制(DeviceOrientation)
关于DeviceOrientation和DeviceMotion两个接口的详细说明,参考了:http://w3c./deviceorientation/spec-source-orientation.html 本文的中实现的用例仅用来测试,在生产环境中应用需要修改其中的参数或者重新编程。
1. 摇一摇
摇一摇功能是很多原生APP都可以实现的功能,如微信中的摇一摇找好友,QQ音乐中的摇一摇换歌等。它们都是利用了手机加速传感器提供的API,当监听到手机加速变化的事件时,根据获取的加速值来执行不同的动作。
接口说明
在Web APP中HTML5 也提供了类似的接口,就是DeviceMotionEvent。DeviceMotion封装了运动传感器数据的事件,可以获取手机运动状态下的运动加速度等数据。
DeviceMotionEvent对象属性列表:
属性 |
释义 |
event.accelaration |
x(y,z):设备在x(y,z)方向上的移动加速度值 |
event.accelarationIncludingGravity |
x(y,z):考虑了重力加速度后设备在x(y,z)方向上的移动加速度值 |
event.rotationRate |
alpha,beta,gamma:设备绕x,y,z轴旋转的角度 |
event.accelarationIncludingGravity与event.accelaration的区别在于前者加入了重力加速度,即在z轴方向加了9.8,在x,y方向上的值两者相同。
旋转速度rotationRate:alpha、beta、gamma的概念与DeviceOrientationEvent一致。 区别在于: DeviceOrientationEvent的值是相对于初始状态的差值,只要设备方向不变,怎么动都不会影响数值; DeviceMotionEvent是相对于之前的某个瞬间值的差值时间比,即变化的速度,一旦设备静止则会恢复为0。
实现方法
Shake对象设计
属性 |
值 |
SHAKE_THRESHOLD |
阈值。阈值越大,触发摇晃事件时手机摇晃的程度越剧烈 |
x |
x方向的加速值 |
y |
y方向的加速值 |
z |
z方向的加速值 |
deviceMotionHandler |
摇晃事件处理程序 |
参数 |
值 |
threshold |
自定义阈值,默认2000 |
callback |
摇晃后的回调函数 |
示例
function Shake(threshold,callback){ this.SHAKE_THRESHOLD = threshold ? threshold : 2000; //定义阈值 this.last_update = 0; this.x = this.y = this.z = this.last_x = this.last_y = this.last_z = 0; this.init = function(){ if (window.DeviceMotionEvent) { window.addEventListener('devicemotion', this.deviceMotionHandler, false); } else { alert('您的浏览器不支持DeviceMotion'); } }; var that = this; this.deviceMotionHandler = function(eventData) { var acceleration = eventData.accelerationIncludingGravity; var curTime = new Date().getTime(); if ((curTime - that.last_update) > 100) { var diffTime = curTime - that.last_update; that.last_update = curTime; that.x = acceleration.x; that.y = acceleration.y; that.z = acceleration.z; var speed = Math.abs(that.x + that.y + that.z - that.last_x - that.last_y - that.last_z) / diffTime * 10000; if (speed > that.SHAKE_THRESHOLD) { if(window.console && console.log){ console.log("shaked"); } if(callback != undefined){ callback(that); } } that.last_x = that.x; that.last_y = that.y; that.last_z = that.z; } } };
使用方法
<!doctype html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>手机摇一摇测试</title> </head> <body> <script> window.onload = function(){ var shake1 = new Shake(2000,function(obj){ alert("shaked"); var r = document.getElementById("result"); r.innerHTML = "x:" + obj.x + ""; r.innerHTML += "y:" + obj.y + ""; r.innerHTML += "z:" + obj.z + ""; }); shake1.init(); }; </script> <div id="result"></div></body></html>
当手机摇晃页面时,会弹出shaked的提示,并且在页面上显示摇晃时的x,y,z方向的加速度值。
扩展应用
给Shake对象的callback参数可以实现不同的摇晃目的,如抽奖。需要在callback函数中调用抽奖系统的接口。 示例
function shakeCallback(){
var odata = {name:"drawprize",act_id : 0000};
HBAPP.Activity.register(odata,function(json){
if(json.error == 0){
if(json.result.draw){
//中奖信息
//......
}
}
});
}
2. 重力感应
重力感应也是原生APP中经常见到的一个功能,在Web App中的应用多见于判断屏幕的旋转方向,以及在此基础上实现的场景应用,如控制页面上物体的左右移动,加减速等。
在Web App中实现以上的功能,需要实时获取屏幕的旋转方向参数,这些参数可以从浏览器的利用HTML5的DeviceOrientation API获得。
接口说明
当浏览器的Orientation发生变化时,触发DeviceOrientation事件,并返回一个DeviceOrientationEvent对象,其属性列表如下:
属性 |
释义 |
alpha |
设备指示的方向,根据指南针的设定情况而定 |
beta |
设备绕x轴旋转的角度 |
gamma |
设备绕y轴旋转的角度 |
注:不同版本的手机操作系统和浏览器,以及不同的应用程序中内置的浏览器对deviceorientation事件的支持不尽相同。尤其在Android平台上,可能会出现有的设备正常工作,有的则毫无反应的情况。
工作原理
根据event对象的三个方向的参数来确定设备的旋转角度。其中,alpha的取值范围是0-360,这个需要根据设备的指南针设定情况而定,一般来说,设备指向正北方向时为0.beta值为设备绕x轴旋转的角度,取值范围为-180-180。gamma取值范围-90-90.
这里面alpha值的意义并不大,主要参考beta和gamma值。 当屏幕从水平沿y轴向左倾斜时gamma值变为负值,向右倾斜变为正值。 档屏幕从水平沿x轴向前倾斜时beta值变为正值,向后倾斜时变为负值。 所以,如果我们设定一个阈值,当beta和gamma的绝对值大于这个阈值时,我们就认为设备发生了旋转。另外根据beta和gamma的值来判断向左倾斜还是向右倾斜,以及倾斜的程度。
实现方式和示例
首先是为浏览器绑定deviceorientation事件和处理程序。
//add deviceorientation event listener
if(window.DeviceOrientationEvent){
window.addEventListener('deviceorientation',DeviceOrientationHandler,false);
}else{
alert("您的浏览器不支持DeviceOrientation");
}
然后在事件处理程序中处理相应的动作
function DeviceOrientationHandler(event){
var alpha = event.alpha,
beta = event.beta,
gamma = event.gamma;
if(alpha != null || beta != null || gamma != null){
dataContainerOrientation.innerHTML = "alpha:" + alpha + "<br />beta:" + beta + "<br />gamma:" + gamma;
//判断屏幕方向
var html = "";
if( Math.abs(gamma) < GAMMA_MIN && Math.abs(beta) > BETA_MAX ){
html = "屏幕方向:Portrait";
}
if( Math.abs(beta) < BETA_MIN && Math.abs(gamma) > GAMMA_MAX ){
html = "屏幕方向:Landscape";
}
var gamma_html = "";
if( gamma > 0 ){
gamma_html = "向右倾斜";
}else{
gamma_html = "向左倾斜";
}
html += "<br />"+gamma_html
stage.innerHTML = html;
}else{
dataContainerOrientation.innerHTML = "当前浏览器不支持DeviceOrientation";
}
}
这个示例中展示了如何利用beta和gamma值来展示屏幕的旋转方向和侧翻方向。要实现更精确的物体判断,还需要复杂的算法来计算。
扩展应用
使用DeviceOrientation API接口可以实现在web中获取手机设备的屏幕旋转方向参数,在示例的基础上进行改进,可以扩展到在屏幕上控制页面元素的移动,实现动画或游戏的目的。例如通过调整屏幕的方向控制页面上的小球走迷宫,控制小车的移动躲避障碍等。
|