偵測裝置方向

Experimental

這是一個實驗中的功能
此功能在某些瀏覽器尚在開發中,請參考兼容表格以得到不同瀏覽器用的前輟。

目前支援 Web 的裝置,已有越來越多可偵測本身的方向(Orientation);也就是說,這些裝置可根據重力牽引的相對關係而改變其畫面方向,同時回報該筆資料。特別是如行動電話的手持式裝置,同樣會判斷這種資訊而自動旋轉其畫面。如此除了能保持正向畫面之外,裝置橫放時亦能以寬螢幕呈現網頁內容。

現有 2 組 JavaScript 事件可處理方向資訊。第一個是 DeviceOrientationEvent 事件。只要加速規偵測到裝置方向的變化,隨即送出此事件。在接收並處理這些方向事件所回報的資料之後,即可針對使用者移動裝置所造成的方向與高度變化,確實做出回應。

第二個為 DeviceMotionEvent 事件。只要加速過程產生變化,隨即送出該事件。此事件用以監聽加速過程的變化,因此不同於 DeviceOrientationEvent 的方向變化。如筆記型電腦中的感測器,一般均能夠偵測 DeviceMotionEvent 而保護移動中的儲存裝置。DeviceOrientationEvent 則較常用於行動裝置。

處理方向事件

若要開始接收方向變換的情形,只要監聽 deviceorientation (en-US) 事件即可:

Note: gyronorm.js is a polyfill for normalizing the accelerometer and gyroscope data on mobile devices. This is useful for overcoming some of the differences in device support for device orientation.

window.addEventListener("deviceorientation", handleOrientation, true);

在註冊了事件監聽器(Event listener。本範例使用 handleOrientation() 函式)之後,將以更新過的方向資料而定期呼叫你的監聽器函式。

方向事件共有 4 組值:

事件處理器(Event handler)函式則如下列:

function handleOrientation(event) {
  var absolute = event.absolute;
  var alpha    = event.alpha;
  var beta     = event.beta;
  var gamma    = event.gamma;

  // Do stuff with the new orientation data
}

方向值說明

所回報的各個軸線值,均是以標準座標而呈現對應各軸線的旋轉量 (Amount of rotation)。可參閱下方所提供的方向與動向資料說明文章以獲得詳細資訊。

方向範例

只要瀏覽器支援 deviceorientation (en-US) 事件,且該執行裝置可偵測自己的方向,均可使用此範例。

先想像花園裡有 1 顆球:

<div class="garden">
  <div class="ball"></div>
</div>

<pre class="output"></pre>

這座花園為 200 像素寬(對,一座小花園),球就位在正中央:

.garden {
  position: relative;
  width : 200px;
  height: 200px;
  border: 5px solid #CCC;
  border-radius: 10px;
}

.ball {
  position: absolute;
  top   : 90px;
  left  : 90px;
  width : 20px;
  height: 20px;
  background: green;
  border-radius: 100%;
}

現在只要移動裝置,球也會跟著移動:

var ball   = document.querySelector('.ball');
var garden = document.querySelector('.garden');
var output = document.querySelector('.output');

var maxX = garden.clientWidth  - ball.clientWidth;
var maxY = garden.clientHeight - ball.clientHeight;

function handleOrientation(event) {
  var x = event.beta;  // In degree in the range [-180,180]
  var y = event.gamma; // In degree in the range [-90,90]

  output.innerHTML  = "beta : " + x + "\n";
  output.innerHTML += "gamma: " + y + "\n";

  // Because we don't want to have the device upside down
  // We constrain the x value to the range [-90,90]
  if (x >  90) { x =  90};
  if (x < -90) { x = -90};

  // To make computation easier we shift the range of
  // x and y to [0,180]
  x += 90;
  y += 90;

  // 10 is half the size of the ball
  // It center the positioning point to the center of the ball
  ball.style.top  = (maxX*x/180 - 10) + "px";
  ball.style.left = (maxY*y/180 - 10) + "px";
}

window.addEventListener('deviceorientation', handleOrientation);

這裡有即時結果 (若無法顯示,可至本文右上角切換回英文原文觀看):

警告:Chrome 與 Firefox 處理角度的方式不同,所以某些軸線可能方向顛倒。

處理動向事件

動向事件與方向事件的處理方式完全相同,但動向事件擁有自己的名稱:devicemotion (en-US)

window.addEventListener("devicemotion", handleMotion, true);

真正改變的是由 DeviceMotionEvent 物件所提供的資訊;且該物件又作為 HandleMotion 函式的參數。

動向事件共有 4 組屬性:

動向值說明

DeviceMotionEvent 物件將提供「裝置位置與方向的變化速度」的相關資訊,並根據 3 組軸線 (可參閱方向與動向資料說明的細節) 提供變化情形。

針對 acceleration (en-US)accelerationIncludingGravity (en-US),這些軸線將對應:

  • x:代表由東至西的軸線
  • y:代表由南至北的軸線
  • z:代表與地面垂直的軸線

針對稍有差異的 rotationRate (en-US),則資訊將對應:

  • alpha:代表與螢幕 (或桌機的鍵盤) 垂直的軸線之旋轉率
  • beta:代表與螢幕平面 (或桌機的鍵盤) 由左至右軸線之旋轉率
  • gamma:代表與螢幕平面 (或桌機的鍵盤) 由下至上軸線之旋轉率

最後,interval (en-US) 代表以毫秒(Millisecond)為單位的時間間隔,是裝置取得資料的頻率。

規範

Specification Status Comment
DeviceOrientation Event Specification Editor's Draft Initial specification.

瀏覽器相容性

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help! (en-US)

Feature Chrome Edge Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
DeviceOrientationEvent 7.0 (Yes) 3.6[1]
6
? ? ?
DeviceMotionEvent (Yes) (Yes) 6 ? ? ?
Feature Android Edge Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
DeviceOrientationEvent 3.0 (Yes) 3.6[1]
6
No support No support 4.2
DeviceMotionEvent (Yes) (Yes) 6 ? ? ?

[1] Firefox 3.6 to 5 supported mozOrientation versus the standard DeviceOrientationEvent event.

參見