檢測裝置方向

安全上下文: 此功能僅在安全上下文(HTTPS)中可用,且支援此功能的瀏覽器數量有限。

越來越多的支援 Web 的裝置能夠確定其方向;也就是說,它們可以報告有關相對於重力拉力的方向變化的資料。特別是,手機等手持裝置可以使用此資訊自動旋轉顯示屏以保持直立,當裝置旋轉使其寬度大於高度時,可以呈現網頁內容的寬屏檢視。

有兩個 JavaScript 事件可以處理方向資訊。第一個是 DeviceOrientationEvent,當加速度計檢測到裝置方向發生變化時會發送此事件。透過接收和處理這些方向事件報告的資料,可以互動式地響應使用者移動裝置引起的方向和傾斜變化。

第二個事件是 DeviceMotionEvent,當加速度發生變化時會發送此事件。它與 DeviceOrientationEvent 不同,因為它監聽的是加速度的變化,而不是方向的變化。通常能夠檢測 DeviceMotionEvent 的感測器包括筆記型電腦中用於保護移動儲存裝置的感測器。 DeviceOrientationEvent 在移動裝置上更為常見。

處理方向事件

要開始接收方向更改,您只需要監聽 deviceorientation 事件。

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

註冊事件監聽器後(在本例中,是一個名為 handleOrientation() 的 JavaScript 函式),您的監聽器函式會定期使用更新的方向資料被呼叫。

方向事件包含四個值

事件處理函式可以像這樣編寫

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

  // Do stuff with the new orientation data
}

注意: parallax 是一個 polyfill,用於標準化移動裝置上的加速度計和陀螺儀資料。這有助於克服裝置對裝置方向支援的一些差異。

方向值說明

每個軸報告的值表示相對於標準座標系的給定軸的旋轉量。這些在 方向和運動資料說明 文章中有更詳細的描述,這裡將對其進行總結。

  • DeviceOrientationEvent.alpha 值表示裝置繞 z 軸的運動,以度為單位,範圍從 0(包含)到 360(不包含)。
  • DeviceOrientationEvent.beta 值表示裝置繞 x 軸的運動,以度為單位,範圍從 -180(包含)到 180(不包含)。這表示裝置的前後運動。
  • DeviceOrientationEvent.gamma 值表示裝置繞 y 軸的運動,以度為單位,範圍從 -90(包含)到 90(不包含)。這表示裝置的左右運動。

方向示例

此示例將在任何支援 deviceorientation 事件並在能夠檢測其方向的裝置上執行的瀏覽器中正常工作。

那麼,讓我們想象一下花園裡的一個球

html
<div class="garden">
  <div class="ball"></div>
</div>
Hold the device parallel to the ground. Rotate along its x and y axes to see the
ball move up/down and left/right respectively.
<pre class="output"></pre>

這個花園寬 200 畫素(是的,這是一個很小的花園),球在中心

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

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

現在,如果我們移動裝置,球會相應地移動

js
const ball = document.querySelector(".ball");
const garden = document.querySelector(".garden");
const output = document.querySelector(".output");

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

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

  output.textContent = `beta: ${x}\n`;
  output.textContent += `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 centers the positioning point to the center of the ball
  ball.style.left = `${(maxY * y) / 180 - 10}px`; // rotating device around the y axis moves the ball horizontally
  ball.style.top = `${(maxX * x) / 180 - 10}px`; // rotating device around the x axis moves the ball vertically
}

window.addEventListener("deviceorientation", handleOrientation);

點選此處 在新視窗中開啟此示例;因為 deviceorientation 在所有瀏覽器的跨域 <iframe> 中都不起作用。

處理運動事件

運動事件的處理方式與方向事件相同,只是它們有自己的事件名稱:devicemotion

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

真正改變的是作為事件監聽器引數傳遞的 DeviceMotionEvent 物件中提供的資訊(在我們示例中為 handleMotion())。

運動事件包含四個屬性

運動值說明

DeviceMotionEvent 物件為 Web 開發者提供有關裝置位置和方向變化速度的資訊。這些變化沿三個軸提供(有關詳細資訊,請參閱 方向和運動資料說明)。

對於 accelerationaccelerationIncludingGravity,這些軸對應於以下內容:

x

表示從西到東的軸

y

表示從南到北的軸

z

表示垂直於地面的軸

對於 rotationRate,情況稍有不同;每種情況下的資訊對應於以下內容:

alpha

表示沿垂直於螢幕(或桌上型電腦的鍵盤)的軸的旋轉速率。

beta

表示沿螢幕(或桌上型電腦的鍵盤)平面從左到右的軸的旋轉速率。

gamma

表示沿螢幕(或桌上型電腦的鍵盤)平面從下到上的軸的旋轉速率。

最後,interval 表示從裝置獲取資料的間隔時間(以毫秒為單位)。

規範

規範
裝置方向和運動
# devicemotion
裝置方向和運動
# deviceorientation

瀏覽器相容性

api.DeviceMotionEvent

api.DeviceOrientationEvent

另見