端末の方向の検出
========

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

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

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

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

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

orientation イベントの処理
-------------------

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


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


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

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

* `DeviceOrientationEvent.absolute`
* `DeviceOrientationEvent.alpha`
* `DeviceOrientationEvent.beta`
* `DeviceOrientationEvent.gamma`

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


```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.acceleration`
* `DeviceMotionEvent.accelerationIncludingGravity`
* `DeviceMotionEvent.rotationRate`
* `DeviceMotionEvent.interval`
### 動きとして示される値

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

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

`x`

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

`y`

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

`z`

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

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

`alpha`

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

`beta`

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

`gamma`

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

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

仕様書
---

| Specification |
| --- |
| DeviceOrientation Event Specification # devicemotion |
| DeviceOrientation Event Specification # deviceorientation |

ブラウザーの互換性
---------

### api.DeviceMotionEvent

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### api.DeviceOrientationEvent

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

関連情報
----

* `DeviceOrientationEvent`
* `DeviceMotionEvent`
* 方向および動きとして示されるデータの説明
* 3D 座標変換での deviceorientation の使用
* Cyber Orb: 端末の向きを使用した 2D 迷路ゲーム (en-US)