端末の方向の検出

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

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

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

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

orientation イベントの処理

方向の変化を受け取り始めるには、 deviceorientation} イベントを待ち受けします。

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

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

イベントリスナー (この例では handleOrientation() という名前の JavaScript 関数) を登録すると、リスナー関数は最新の方向データとともに、周期的に呼び出されます。

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

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

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

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

方向として示される値

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

  • DeviceOrientationEvent.alpha (en-US) の値は z 軸を中心にした端末の動きを表し、0 以上 360 未満の範囲による度数で表されます。
  • DeviceOrientationEvent.beta (en-US) の値は x 軸を中心にした端末の動きを表し、-180 以上 180 未満の範囲の値による度数で表されます。これは端末の前後の動きです。
  • DeviceOrientationEvent.gamma (en-US) の値は y 軸を中心にした端末の動きを表し、-90 以上 90 未満の範囲の値による度数で表されます。これは端末の左右の動きです。

このサンプルは方向を検出可能な端末上で、 deviceorientation イベントに対応するブラウザーで実行する場合に動作します。

庭にボールがあると考えてください。

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

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

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.top = `${(maxY * y) / 180 - 10}px`;
  ball.style.left = `${(maxX * x) / 180 - 10}px`;
}

window.addEventListener("deviceorientation", handleOrientation);

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

motion イベントの処理

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

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

実際どのように変化したかの情報は、HandleMotion 関数の引数として渡す DeviceMotionEvent オブジェクトが提供します。

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

動きとして示される値

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

acceleration (en-US) および accelerationIncludingGravity (en-US) で対応する軸は以下のとおりです。

  • x: 西から東へ向かう軸を表します。
  • y: 南から北へ向かう軸を表します。
  • z: 地面から直立する軸を表します。

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

  • alpha: スクリーン (デスクトップ環境ではキーボード) から直立する軸を表します。
  • beta: スクリーンの面 (デスクトップ環境ではキーボード) の左から右へ向かう軸に沿った回転量を表します。
  • gamma: スクリーンの面 (デスクトップ環境ではキーボード) の下から上へ向かう軸に沿った回転量を表します。

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

仕様書

Specification
DeviceOrientation Event Specification
# devicemotion
DeviceOrientation Event Specification
# deviceorientation

ブラウザーの互換性

api.DeviceMotionEvent

BCD tables only load in the browser

api.DeviceOrientationEvent

BCD tables only load in the browser

関連情報