如今不少H5页面都会使用到相似摇一摇等功能,这其实只是应用了HTML5上的传感器api的其中一部分,如下针对本身学习和使用作了个总结,以作备忘和分享。javascript
w3c定义了不少传感器的API,有不少还在草案阶段,兼容性和可用性不是很高,但在可预见的将来,相信这些强大的API可让HTML5更增强大,实现更多原来在native APP上才能实现的功能、应用。html
DOM Sensor Event | Sensor Type | Data Type | Units |
---|---|---|---|
devicetemperature | A ambient temperature sensor | double | degree Celsius (ºC) |
devicepressure | A pressure sensor | double | kiloPascal (kP) |
devicehumidity | A releative humidity sensor | double | percentage |
devicelight | A light sensor | double | Lux |
devicenoise | A ambient noise sensor | double | dbA |
deviceproximity | A proximity sensor | double | centimetres (cm) |
w3c规定了设备传感器能够经过事件来触发访问数据,例如光线传感器经过如下方式获取数据:html5
if('ondevicelight' in window) { window.addEventListener("devicelight", function(event) { //light level is returned in lux units console.log(event.value + " lux"); }); } if('onlightlevel' in window){ window.addEventListener("lightlevel", function(event) { //light value can be dim, normal or bright console.log(event.value); }); }
目前最经常使用的就是基于手机陀螺仪的重力传感器,经过它能够实现摇一摇、赛车游戏、惯性导航等应用。java
deviceorientation 提供设备的物理方向信息,表示为一系列本地坐标系的旋角。git
devicemotion 提供设备的加速信息,表示为定义在设备上的坐标系中的α坐标。其还提供了设备在坐标系中的自转速率。若可行的话,事件应该提供设备重心处的加速信息。github
如下是w3c解释重力感应器时的经典示意解释:
(坐标系遵循右手定则,单位是角度。P.S. Firefox中是弧度)web
设备围绕z轴的旋转角度为α,α角度的取值范围在[0,360)。api
![]() |
![]() |
---|---|
设备在初始位置,地球(XYZ)和机身(xyz)对齐(即水平放置,顶端向北,屏幕朝上)。 | 设备围绕z轴的旋转角度为α,并与先前的x和y轴位置对比,显示x,y轴新坐标为x0和y0。 |
设备围绕x轴的旋转角度为β,β角度的取值范围在(-180,180)。ide
设备围绕x轴的旋转角度为β,并与先前的y和z轴的位置对比,显示y,z轴新坐标为y0和z0。post
设备围绕y轴的旋转角度为γ,γ角度的取值范围在(-90,90)。
设备围绕y轴的旋转角度为γ,并与先前的x和z轴的位置对比,显示x,z轴新坐标为x0和z0。
注册一个deviceorientation事件的接收器:
window.addEventListener("deviceorientation", function(event) { // 处理event.alpha、event.beta及event.gamma }, true);
将设备放置在水平表面,屏幕顶端指向西方,则其方向信息以下:
{ alpha: 90, beta: 0, gamma: 0 };
iOS 和 Android 两家系统对于手机硬件提供 alpha 数值不尽相同,若是在iOS上会有webkitCompassHeading,webkitCompassHeading表示「手机与地球正北方的夹角」,而 Android 则直接用 alpha 便可。( 不过若是不是 Chrome 又不尽相同,反正若是不一样,就是在进行角度的加减便可)。另外github上有个库将不一样的手机的参数统一了,可使用Device API Normaliser。
为了得到罗盘指向,能够简单的使用360度减去alpha。若设被平行于水平表面,其罗盘指向为(360 - alpha)。 若用户手持设备,屏幕处于一个垂直平面且屏幕顶端指向上方。beta的值为90,alpha和gamma无关。 用户手持设备,面向alpha角度,屏幕处于一个垂直屏幕,屏幕顶端指向右方,则其方向信息以下:
{ alpha: 270 - alpha, beta: 0, gamma: 90 };
注册一个devicemotion事件的接收器:
window.addEventListener("devicemotion", function(event) { // 处理event.acceleration、event.accelerationIncludingGravity、 // event.rotationRate和event.interval }, true);
将设备放置在水平表面,屏幕向上,acceleration为零,则其accelerationIncludingGravity信息以下:
{ x: 0, y: 0, z: 9.81 };
设备作自由落体,屏幕水平向上,accelerationIncludingGravity为零,则其acceleration信息以下:
{ x: 0, y: 0, z: -9.81 };
将设备安置于车辆至上,屏幕处于一个垂直平面,顶端向上,面向车辆后部。车辆行驶速度为v,向右侧进行半径为r的转弯。设备记录acceleration和accelerationIncludingGravity在位置x处的状况,同时设备还会记录rotationRate.gamma的负值:
{ 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} };
简单的摇一摇实现:
if (window.DeviceMotionEvent) { window.addEventListener('devicemotion',deviceMotionHandler, false); var speed = 30;//speed var x = y = z = lastX = lastY = lastZ = 0; function deviceMotionHandler(eventData) { var acceleration =eventData.accelerationIncludingGravity; x = acceleration.x; y = acceleration.y; z = acceleration.z; if(Math.abs(x-lastX) > speed || Math.abs(y-lastY) > speed || Math.abs(z-lastZ) > speed) { //简单的摇一摇触发代码 alert(1); } } lastX = x; lastY = y; lastZ = z; }
https://dvcs.w3.org/hg/dap/ra...
http://w3c.github.io/deviceor...
https://developer.mozilla.org...
http://www.h5-share.com/artic...
http://www.haorooms.com/post/...