HTML5設備傳感器總結

前言

如今不少H5頁面都會使用到相似搖一搖等功能,這其實只是應用了HTML5上的傳感器api的其中一部分,如下針對本身學習和使用作了個總結,以作備忘和分享。javascript

Device API

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

  1. deviceorientation 提供設備的物理方向信息,表示爲一系列本地座標系的旋角。git

  2. devicemotion 提供設備的加速信息,表示爲定義在設備上的座標系中的α座標。其還提供了設備在座標系中的自轉速率。若可行的話,事件應該提供設備重心處的加速信息。github

如下是w3c解釋重力感應器時的經典示意解釋:
(座標系遵循右手定則,單位是角度。P.S. Firefox中是弧度)web

  • 設備圍繞z軸的旋轉角度爲α,α角度的取值範圍在[0,360)。api

start.png c-rotation.png
設備在初始位置,地球(XYZ)和機身(xyz)對齊(即水平放置,頂端向北,屏幕朝上)。 設備圍繞z軸的旋轉角度爲α,並與先前的x和y軸位置對比,顯示x,y軸新座標爲x0和y0。
  • 設備圍繞x軸的旋轉角度爲β,β角度的取值範圍在(-180,180)。
    a-rotation.pngide

設備圍繞x軸的旋轉角度爲β,並與先前的y和z軸的位置對比,顯示y,z軸新座標爲y0和z0。post

  • 設備圍繞y軸的旋轉角度爲γ,γ角度的取值範圍在(-90,90)。
    b-rotation.png

設備圍繞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/...

相關文章
相關標籤/搜索