HTML5 DeviceOrientation 接口应用

本文档旨在通过介绍HTML5 DeviceOrientation 和DeviceMotion两个接口的使用,来实现某些场景应用,如

  • 摇一摇功能(DeviceMotion)
  • 重力感应方向控制(DeviceOrientation)

关于DeviceOrientation和DeviceMotion两个接口的详细说明,参考了:http://w3c.github.io/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 摇晃事件处理程序
方法 作用
init 初始化Shake对象
参数
threshold 自定义阈值,默认2000
callback 摇晃后的回调函数

示例

<pre><code>
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;
            }
        }
        
    }; 

</code></pre>

使用方法

<pre>
<code>
<!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 + "<br />";
r.innerHTML += "y:" + obj.y + "<br />";
r.innerHTML += "z:" + obj.z + "<br />";
});
shake1.init();
};
</script>
<div id="result"></div>
</body>
</html>
</code>
</pre>
当手机摇晃页面时,会弹出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中获取手机设备的屏幕旋转方向参数,在示例的基础上进行改进,可以扩展到在屏幕上控制页面元素的移动,实现动画或游戏的目的。例如通过调整屏幕的方向控制页面上的小球走迷宫,控制小车的移动躲避障碍等。


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • 来源 https://zhuanlan.zhihu.com/p/24425116 给深度学习入门者的Python快...
    海浪java阅读 5,767评论 0 40
  • 继续说《大学》,昨天讲到“大学之道”,就是做一个顶天立地的大人的学问,儒家为此制定了三纲和八目。“纲”原指渔网上的...
    莲连阅读 325评论 0 1
  • 非虚构写作需要讲证据 非虚构写作,顾名思义,不能虚构。基本事实必须有依据,讲证据。而国内的纪实文学,这一点做得很差...
    王佩阅读 1,493评论 6 49
  • ①职场上,后来很多的不愉快和难受,其实是有迹可循的。一开始发现价值观不同的两人,协商好互相退一步,磨合磨合就能把状...
    一只2b兔子阅读 194评论 0 0
  • 我取名叫城市流浪汉,因为这是真实写照! 今天无意间,第一次登陆简书,浏览到很多即兴短文,很生活很有感触,发泄情绪和...
    城市流浪汉阅读 179评论 0 0