端末の方向の検出

安全なコンテキスト用: この機能は一部またはすべての対応しているブラウザーにおいて、安全なコンテキスト (HTTPS) でのみ利用できます。

次第に、ウェブを利用可能な端末は、自身の方向を特定できるようになってきました。つまり端末は、重力との関係による自身の向きの変化を示すデータを報告できます。特に携帯電話のようなハンドヘルド端末は、表示内容が直立し続けるよう自動的に回転させるためにこの情報を使用できます。画面の幅が高さより大きくなるように端末を回転させたときは、ウェブコンテンツをワイドスクリーン表示にします。

方向の情報を制御する JavaScript イベントが 2 つあります。ひとつは DeviceOrientationEvent であり、加速度センサーが端末の方向の変化を検出したときに発生します。 orientation イベントが報告するデータを受け取って処理することで、ユーザーが端末を動かすことによる方向や高さの変化に対してインタラクティブに応答できるようになります。

もうひとつのイベントは DeviceMotionEvent であり、加速度が変化したときに発生します。こちらは方向ではなく加速度の変化を監視することが、DeviceOrientationEvent との違いです。一般的に DeviceMotionEvent を検出できるセンサーには、可動部があるストレージ装置を保護するためノートパソコンに内蔵するものも含みます。DeviceOrientationEvent は、モバイル端末でとても一般的です。

orientation イベントの処理

方向の変化を受け取り始めるために必要なことは、 deviceorientation イベントを待ち受けすることだけです。

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

イベントリスナー(この場合は handleOrientation() と呼ばれる JavaScript 関数)を登録すると、リスナー関数は定期的に更新された方向データを取得します。

orientation イベントは 4 つの値を持ちます。

イベントハンドラー関数は以下のようなものです。

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

  // 新たな方向データに基づいて処理を行う
}

メモ: parallax は、モバイル端末の加速度センサーとジャイロスコープのデータを正規化するためのポリフィルです。これは、端末の方向に対する対応の違いを克服するのに有益です。

方向として示される値

それぞれの軸で報告される値は、標準座標系の軸を中心にした回転量を表します。これらは方向および動きとして示されるデータの説明の記事で詳しく説明しており、ここでは概要を記載します。

  • 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>
端末を地面に並行に置いてください。 X 軸と Y 軸に沿って回転させ、ボールがそれぞれ上下左右に移動するのを確認しましょう。
<pre class="output"></pre>

庭の幅は 200 ピクセルであり(小さな庭です)、ボールは中心にあります。

css
.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%;
}

端末を動かすと、その動きに応じてボールが移動します。

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; // [-180,180) の範囲で角度を表す
  let y = event.gamma; // [-90,90) の範囲で角度を表す

  output.textContent = `beta: ${x}\n`;
  output.textContent += `gamma: ${y}\n`;

  // 端末をひっくり返したくはないため、
  // x の値を [-90,90] の範囲に制限する
  if (x > 90) {
    x = 90;
  }
  if (x < -90) {
    x = -90;
  }

  // 計算を容易にするため、x および y の値の範囲を
  // 0 から 180 に変換する
  x += 90;
  y += 90;

  // 10 は、ボールのサイズの半分である。
  // これにより、配置場所をボールの中心に合わせる
  ball.style.left = `${(maxY * y) / 180 - 10}px`; // Y 軸を中心に端末を移動させると、ボールが水平に移動
  ball.style.top = `${(maxX * x) / 180 - 10}px`; // X 軸を中心に端末を移動させると、ボールが垂直に移動
}

window.addEventListener("deviceorientation", handleOrientation);

こちらをクリックすると、新しいウィンドウでこの例を開きます。 deviceorientation はどのブラウザーでも別オリジンの <iframe> では動作しないからです。

motion イベントの処理

motion イベントは orientation イベントと同じ方法で扱えますが、イベント名は devicemotion になります。

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

実際どのように変化したかの情報は、 DeviceMotionEvent オブジェクトが提供します。これはイベントリスナー(この例では handleMotion())の引数として渡されます。

motion イベントは 4 つのプロパティを持ちます。

動きとして示される値

DeviceMotionEvent オブジェクトはウェブ開発者に、端末の位置や方向が変化した速度の情報を提供します。変化量は 3 つの軸 (詳しくは方向および動きとして示されるデータの説明をご覧ください) に沿って表します。

acceleration および accelerationIncludingGravity で対応する軸は以下のとおりです。

x

西から東へ向かう軸を表します。

y

南から北へ向かう軸を表します。

z

地面から直立する軸を表します。

rotationRate では状況が若干異なります。こちらの情報はそれぞれ以下のように対応します:

alpha

画面(デスクトップ環境ではキーボード)から直立する軸を表します。

beta

画面の表面(デスクトップ環境ではキーボード)の左から右へ向かう軸に沿った回転量を表します。

gamma

画面の表面(デスクトップ環境ではキーボード)の下から上へ向かう軸に沿った回転量を表します。

最後に interval は、端末からデータを取得する間隔をミリ秒単位で表します。

仕様書

Specification
Device Orientation and Motion
# devicemotion
Device Orientation and Motion
# deviceorientation

ブラウザーの互換性

api.DeviceMotionEvent

Report problems with this compatibility data on GitHub
desktopmobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
DeviceMotionEvent
DeviceMotionEvent() constructor
acceleration
accelerationIncludingGravity
interval
requestPermission() static method
Experimental
rotationRate

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support
Experimental. Expect behavior to change in the future.

api.DeviceOrientationEvent

Report problems with this compatibility data on GitHub
desktopmobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
DeviceOrientationEvent
DeviceOrientationEvent() constructor
absolute
alpha
beta
gamma
requestPermission() static method
Experimental

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support
Experimental. Expect behavior to change in the future.
See implementation notes.

関連情報