如今不少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/...