重力传感器是一个非常常见的内置在智能手机等移动设备中的传感器,基本作用就是获得移动设备的重心。当移动设备倾斜或翻转时,重心会发生变化,而重力传感器将如实地记录下重心变化的过程并通过数据反映出来。

本文将通过HTML5的Device API中的deviceorientation制作一个重力感应球的例子,供读者参考。

deviceorientation所在的地址是:http://dev.w3.org/geo/api/spec-source-orientation.html。

由于安全问题,浏览器可能会默认关闭一些配置,因此读者需要从欧朋浏览器地址栏中输入opera:config后回车,找到需要的相关参数,进行调整

如果你在测试时,发现无法监测到deviceorientation传出来的值,有可能是因为关闭了对deviceorientation的支持,那你可以试着照上图所示的方式,在地址栏中输入opera:config,回车,然后找到Orientation选项并勾选上

1. 了解重力传感器

传感器是移动互联网Web App开发中非常重要的一个设备,涉及多个应用概念。在HTML5的Device API中,DeviceOrientation事件规范提供了3个DOM事件,分别是:deviceorientation、compassneedscalibration和devicemotion。本节主要讲解的是deviceorientation。

DeviceOrientation规范定义的是返回alpha、beta和gamma三个值,如下面的代码所示:

window.addEventListener("deviceorientation", function(event){

//返回值event.alpha、event.beta、event.gamma

}, true);

当设备水平放在桌面上时,其event返回的值如下:

{alpha: 90,

beta: 0,

gamma: 0};

而此时,其设备的朝向值应为360-alpha(当设备翻转时,以此公式为基础进行朝向运算),

当设备的转动变成以x轴为中心自转时,其event返回的值如下:

{alpha: 90,

beta: 90,

gamma: 0};

当设备的转动变成以z 轴为中心自转时,则alpha值发生变化,

当设备的转动变成以y 轴为中心自转时,则gamma值发生变化,

当DeviceOrientation规范的Devicemotion事件的加速度计还允许有重力时,则会出现:

{x: 0,

y: 0,

z: 9.81};

而这时,如果设备处于自由落体的情况时,它的值应该是:

{x: 0,

y: 0,

z: -9.81};

如果设备在高速行驶的汽车中时,它的值应该是(这是复杂应用,目前还没有良好的支持,

有兴趣的读者可以继续深入研究):

{acceleration: {x: v^2/r, y: 0, z: 0},

accelerationIncludingGravity: {x: v^2/r, y: 0, z: 9.81},

rotationRate: {alpha: 0, beta: 0, gamma:-v/r*180/pi} };

2. 重力感应球示例

为了让读者更好地了解重力传感器,建立起感性的认识,我们通过重力感应球的示例来展示重力传感器的开发过程和技巧。

重力传感器示例的代码如代码如下:

重力感应球

style=color:#fff;height:30px;line-height:60px;font-size:26px;margin-top:25px;

margin-bottom:35px;">重力感应球

style="color:#ccc;font-size:18px;margin-left:20px;margin-right:20px;margin-top:

16px;">HTML5的Device API集成了调取重力感应和重力加速的功能。基于此功能,欧朋浏览器 HTML5

体验版可以实现重力感应,并在网页上呈现效果。此demo就是利用了这个特性。晃动手机,便可实现小球在

网页上滚动的特效。

关闭提示

style="z-index:1000;position:absolute;left:0px;top:30px;">

οnclick="showhelp('')">

function hiddeDiv(id){

document.getElementById('helpme').style.display='none';

}

function showhelp(){

document.getElementById('helpme').style.display='';

}

style="margin-top:0px;margin-left:0px;z-index:10;">

var cur_x = 0;

var cur_y = 0;

var ball_radius = 50; //球的半径,用来判断是否靠近边界,进行碰撞检测用

var initialized = false; //初始化的值

var ww;

var wh;

var speed_x = 0;

var speed_y = 0;

var accel_x;

var accel_y;

var friction_accel = 0.02; //摩擦系数

var interval = 33; //毫秒数, 约为30帧每秒

var bg_color = "#EEEEEE";

var fg_color = "#333";

var absorbing_rate = 0.5; //弹力消耗比例

var gunball=new Image();

gunball.src="opera_ball.png"; //实例化的滚球的图像

var opera_pix_bg=new Image();

opera_pix_bg.src="opera_pix_bg2.png"; //实例化的背景图

function inSameDirection(a, b){ //方向判断函数

return a > 0 && b > 0 || a <= 0 && b <= 0;

}

function getCurpos(cur_pos, speed, accel, boundary){ //当前位置判断函数

if(speed == 0 &&Math.abs(accel) <= friction_accel)

return [cur_pos, speed];

start_speed = speed;

f_accel = (speed > 0 ? -friction_accel:friction_accel); //摩擦力导致速度变慢

speed += accel + f_accel; //速度的方向被改变了

if(!inSameDirection(f_accel, accel) &&

!inSameDirection(f_accel, start_speed) &&

!inSameDirection(start_speed, speed)){

//因为摩擦,球的速度逐渐为0

speed = 0;

}

cur_pos += (start_speed + speed)/2; //边界检测

if(cur_pos> boundary - ball_radius){

cur_pos= boundary - ball_radius;

speed = -speed * absorbing_rate;

}

else if(cur_pos < 0){

cur_pos = 0;

speed = -speed * absorbing_rate;

}

return [cur_pos, speed];

}

function physics(){ //物理运动计算函数

var x = getCurpos(cur_x, speed_x, accel_x, ww);

cur_x = x[0];

speed_x = x[1];

var y = getCurpos(cur_y, speed_y, accel_y, wh);

cur_y = y[0];

speed_y = y[1];

}

function paint(){ //绘图函数

var ball_canvas = document.getElementById('ball');

var ctx = ball_canvas.getContext('2d');

physics(); //引入物理运动计算的函数

ctx.drawImage(opera_pix_bg, 0,0, ww, wh );

ctx.drawImage(gunball, cur_x,cur_y, 50, 50 );

setTimeout("paint()", interval);

}

function clearCanvas(){ //擦除画布的函数

var ball_canvas = document.getElementById('ball');

var ctx = ball_canvas.getContext('2d');

}

function update(evt){ //更新画布的函数

var ball_canvas = document.getElementById('ball');

if(ball_canvas.width != window.outerWidth ||

ball_canvas.height != window.outerHeight){

ball_canvas.width = window.outerWidth;

ball_canvas.height = window.outerHeight;

clearCanvas();

}

ww = ball_canvas.width;

wh = ball_canvas.height;

//根据重力传感器的值计算加速度

accel_x = Math.sin(evt.gamma/180 * Math.PI);

accel_y = Math.sin(evt.beta/180 * Math.PI);

if(!initialized){

cur_x = ww/2 + ball_radius; //滚球当前位置的x坐标值

cur_y = wh/2 + ball_radius; //滚球当前位置的y坐标值

initialized = true;

clearCanvas();

paint(); //调用绘图函数

}

}

function preload(){

var ball_canvas = document.getElementById('ball');

if(ball_canvas.width != window.outerWidth ||

ball_canvas.height != window.outerHeight){

ball_canvas.width = window.outerWidth;

ball_canvas.height = window.outerHeight;

}

ww = ball_canvas.width;

wh = ball_canvas.height;

paint();

}

preload();

window.addEventListener('deviceorientation', update, true);

晃动、翻转设备时,球会随着设备的变动而滚动弹跳。本代码的执行效果如下图:

3. 本例小结

本例是众多传感器设备通过HTML5标准在浏览器上实现的一个典型案例。到目前为止,如果开发者要做重力传感器的实验,又买不起iPhone或者iPad的话,搞个便宜的Android系统手机,装上欧朋H5就可以试验了。

在开发重力传感器的时候,新手往往会忽略几个问题,在此我们特意提出来供读者引以为鉴。

(1) 传感器得出来的值是非稳定态的,往往有噪声数据,因此,如果开发者直接使用传感器传过来的值进行绘图,一定会出现滚球闪动和瞬间不受控的现象。很多开发者在滤波面前往往一愁莫展,网上大量的各种滤波算法都是有用的,而且是合理的,例如平均值滤波、去除最大值和最小值的滤波、加权平均滤波,甚至卷积分滤波等。但是,经过实践,我们总结出一个很有效的。

小经验 通过setInterval这样的定时器去取值,把帧数定在30帧左右,就可以实现99%以上的完美滤波。我们把这个方法称为时间点抽样滤波。

(2) iOS系统里(iPhone、iPad和iPod)的Safari在直接获取传感器数据时,往往没有噪声,原因是浏览器已经消过噪了。这是好事,也是坏事。好事是开发者不用操心传感器的示波不稳定问题。坏事是开发者得到的数据都是经过过滤的,而且没有办法得到第一手数据,往往在特殊情况下不利。在摇动、晃动等行为发生时,用重力传感器是不合适的。在标准中, devicemotion事件可以判断摇动、晃动等行为的。

虽然在标准中有提示可以通过加速度和角度来计算摇动、晃动等行为,但很多开发者可能会不适应,建议使用devicemotion事件。

html手机重力,HTML5重力传感设备相关推荐

  1. html5 360 重力 感应,H5案例分享:html5重力感应事件

    html5重力感应事件 一.手机重力感应图形分析 1.设备围绕z轴的旋转角度为α,α角度的取值范围在[0,360). 设备在初始位置,与地球(XYZ)和身体(XYZ)某个位置对齐. 设备围绕z轴的旋转 ...

  2. 移动设备wap手机网页html5通过特殊链接:打电话,发短信,发邮件详细教程

    移动设备wap手机网页html5通过特殊链接:打电话,发短信,发邮件详细教程 原文地址:https://www.luoxiao123.cn/1120-2.html 最近逍遥乐在寻找手机网页调用系统短信 ...

  3. 手机 html5评测,三款主流手机浏览器HTML5性能横向评测

    到目前为止带给大家更多的是一种神秘感,我们并未看到很多以HTML5为主的网站在我们生活中出现,正是因为这份神秘感让我们想对HTML5进行一次深入的探秘,去了解一下什么是HTML5,并且HTML5究竟应 ...

  4. 物联网跟人的神经网络相似通过各种信息传感设备

    物联网通过信息传感设备将各种物品与互联网连接起来,实现物品的自动识别.定位.跟踪.控制和信息的互换 试题分析:通过物联网将物品与互联网相连接,实现物品的自动识别.定位.跟踪.控制和信息的互联.共享,体 ...

  5. html5手机排行,三款主流手机浏览器HTML5性能横向评测

    到目前为止HTML5带给大家更多的是一种神秘感,我们并未看到很多以HTML5为主的网站在我们生活中出现,正是因为这份神秘感让我们想对HTML5进行一次深入的探秘,去了解一下什么是HTML5,并且HTM ...

  6. softAP配网:用Android手机为linux无屏设备输入wifi密码

    softAP配网,即利用设备的无线芯片,将设备进入到softAP模式,开启一个无线局域网,手机(或其它移动设备)通过连入设备开启的无线局域网后,向设备发送路由器的ssid及password等信息,让设 ...

  7. Android 10 + 适用于国内各大手机厂商的开放匿名设备标识(OAID),若不支持OAID则随机生成一个全局唯一标识(GUID)

    源码见:https://github.com/gzu-liyujiang/Android_CN_OAID 本项目用于获取国内各大Android手机厂商的开放匿名设备标识(OAID).遵循谷歌官方使用A ...

  8. 拍摄短视频需要哪些工具?一部手机还不够,简单的设备你得有

    拍摄短视频需要哪些工具?一部手机还不够,简单的设备你得有 正所谓,工欲善其事必先利其器,拍摄短视频亦是如此,跟专业的短视频拍摄团队比不了,我们如果只是个人做短视频,又想要做出来一些成绩,那么一部手机其 ...

  9. Unity实现在Android端获取Android手机的唯一ID(设备号)(亲测Android11可用)

    Unity实现在Android端获取Android手机的唯一ID(设备号)(亲测Android11可用) 备注:测试版本Unity2020,理论上Unity2018以上都可用,未做测试 - 文章初衷 ...

最新文章

  1. 行人搜索也可以Anchor-Free?这篇CVPR 2021论文给出了答案
  2. C++走向远洋——39(指向学生类的指针)
  3. 想学测试如何入门和学习软件测试?今天我就好好给你唠唠
  4. python excel 自动化-简直出神入化,教你用Python控制Excel实现自动化办公
  5. 使用命令将单个java文件打包为jar
  6. 从零开始搭建spring-cloud(1) ----eureka
  7. 洛谷 - P4197 Peaks(Kruskal重构树+dfs序+主席树)
  8. 设计专业作品展示舞台,灵感源泉
  9. GBase数据库日常运维操作(一)
  10. 汽车租赁系统V1.0
  11. Reverse Engineering the NC ECU (revisited) -- SH7508
  12. Xtrabackup使用指南 InnoDB数据备份工具
  13. 强势来袭!国内首本大型分布式架构笔记浴火新生
  14. 软件工程头歌人机交互部分设计用例
  15. word用尾注插入参考文献—删除横线,空格等
  16. 一次同余式和中国剩余定理
  17. 微信读书排版引擎自动化测试
  18. 阿里“城市大脑”发布 目的是向纵深推进
  19. linux 调度类,了解RT调度类linux的dequeue_rt_stack()
  20. yii学习的第三天(两种验证方式)

热门文章

  1. 打开Visual Studio 2017报错:未能正确加载“VSTS for Database Professionals Sql Server Data-tier Application”包
  2. cycript常用语法指令
  3. NLP:HMM、MEMM、CRF序列标注
  4. having查询不含null的集合
  5. 音视频开发(三十九):Android视频缓存之AndroidVideoCache
  6. 【180930】WPF蜘蛛纸牌游戏源码
  7. 转载:艺用人体解剖(学习用书)(中央美术学院基础教学)
  8. windows系统一键关停系统的脚本
  9. 破产姐妹第一季/全集2 Broke Girls迅雷下载
  10. [直播预告]当ROS邂逅无人驾驶汽车(2018年9月26日)ROS meets Self-driving Cars