Chrome Dev Summit 2018 is happening now and streaming live on YouTube. Watch now.

端末画面の向きと端末のモーション

端末のモーション イベントおよび画面の向きのイベントによって、モバイル端末に組み込まれた加速度計、ジャイロスコープ、およびコンパスの機能を利用することができます。

これらのイベントにはさまざまな用途があり、ゲームでキャラクターの向きやアクションを制御することもできます。 位置情報とあわせて使用すると、より正確なターンバイターンのナビゲーションの作成や、特定の場所に関する情報提供が可能になります。

TL;DR

  • 端末の上端を検出し、端末の回転状態を特定します。
  • 端末のモーション イベントおよび画面の向きのイベントに応答するタイミングと方法について説明します。

どちらの端が上か?

端末のモーション イベントおよび画面の向きのイベントによって返されるデータを使用するためには、その値の意味を理解する必要があります。

地球の座標フレーム

地球座標フレームでは、重力と標準的な磁北方向を基準とした軸を用いて、XY、および Z の値で座標を記述します。

座標系
X 東西方向を表します(東が正)。
Y 南北方向を表します(北が正)。
Z 地面に対して垂直な上下方向を表します(上が正)。

端末の座標フレーム

端末の座標フレームの図
端末の座標フレームの図

端末の座標フレームでは、端末の中心を基準とした軸を用いて、xy、および z の値で座標を記述します。

座標系
X 画面の水平面において右方向が正。
Y 画面の水平面において上方向が正。
Z 画面またはキーボードに直交して遠ざかる方向が正。

携帯電話やタブレットでは、端末の向きは画面の典型的な向きを基準とします。 携帯電話やタブレットの場合、端末が縦表示になっている状態を基準とします。 デスクトップまたはラップトップ コンピュータの場合は、画面の向きはキーボードに対する向きとして考えられます。

回転データ

回転データはオイラー角で返されます。これは、端末の座標フレームと地球の座標フレーム間の角度の差を表します。

alpha

端末の座標フレームの図
端末の座標フレームにおける alpha の図

回転軸は Z 軸です。端末の上部が真北を向いている場合、alpha の値は 0° です。 端末が反時計回りに回転するにつれて alpha の値は増加します。

beta

端末の座標フレームの図
端末の座標フレームにおける beta の図

回転軸は X 軸です。端末の上部と下部が地表から等距離にある場合、beta の値は 0° です。 端末の上部が地表に近づくように傾くにつれて、値が増加します。

gamma

端末の座標フレームの図
端末の座標フレームの gamma の図

回転軸は Y 軸です。端末の左端と右端が地表から等距離にある場合、gamma の値は 0° です。 端末の右端が地表に近づくように傾くにつれて、値が増加します。

端末画面の向き

端末画面の向きのイベントは回転データを返します。このデータには、端末の前後および左右への傾き具合、スマートフォンやノートパソコンにおけるコンパスの有無、端末画面の方向など、さまざまな情報が含まれます。

端末画面の向きのイベントは慎重に使用し、利用するにあたってテストを実施してください。また、このイベントが発生するたびに UI を更新することは避けて、代わりに requestAnimationFrame に同期するようにしてください。

端末画面の向きのイベントの扱い

端末画面の向きのイベントにはいくつかの用途があります。以下に例を挙げます。

  • ユーザーの移動に伴いマップを更新します。
  • 視差効果の追加など、UI の細かい調整を行います。
  • 位置情報と組み合わせると、ターンバイターンのナビゲーションに使用できます。

サポート状況を確認して、イベントをリッスンする

DeviceOrientationEvent をリッスンするには、まずこのイベントがブラウザでサポートされていることを確認します。次に、deviceorientation イベントを受け取る window オブジェクトにイベント リスナーを登録します。

if (window.DeviceOrientationEvent) {
  window.addEventListener('deviceorientation', deviceOrientationHandler, false);
  document.getElementById("doeSupported").innerText = "Supported!";
}

端末画面の向きのイベントを処理する

端末画面の向きのイベントは、端末の位置や向きが変化したときに発生します。 このイベントは、地球の座標フレームを基準として、端末の現在位置の変化量を返します。

このイベントは通常、alphabeta、および gamma の3 つのプロパティを返します。 Mobile Safari では、追加のパラメータ webkitCompassHeading がコンパス方位とともに返されます。

端末のモーション

端末画面の向きのイベントは回転データを返します。このデータには、端末の前後および左右への傾き具合、スマートフォンやノートパソコンにおけるコンパスの有無、端末画面の方向など、さまざまな情報が含まれます。

一方、端末の現在の動きを知りたい場合は、端末のモーション イベントを使用します。rotationRate は °/sec 単位で、accelerationaccelerationWithGravity は m/sec2 単位で提供されます。ブラウザによって実装に差異があるので注意してください。

端末モーション イベントの用途

端末モーション イベントにはいくつかの用途があります。以下に例を挙げます。

  • データを更新するためのシェイク操作。
  • ゲームでキャラクターをジャンプさせたり動かしたりする。
  • 健康およびフィットネス用のアプリに使用する。

サポート状況を確認して、イベントをリッスンする

DeviceMotionEvent をリッスンするには、まずこのイベントがブラウザでサポートされていることを確認します。 次に、devicemotion イベントをリッスンする window オブジェクトにイベント リスナーを登録します。

if (window.DeviceMotionEvent) {
  window.addEventListener('devicemotion', deviceMotionHandler);
  setTimeout(stopJump, 3*1000);
}

端末モーション イベントの扱い

端末のモーション イベントは一定間隔で発生し、その時点での端末の回転(°/sec)および加速度(m/sec2)のデータを返します。一部の端末では、重力の影響を除外するためのハードウェアを備えていません。

このイベントは、accelerationIncludingGravityacceleration(重力の影響を排除)、rotationRate、および interval の 4 つのプロパティを返します。

たとえば、平らなテーブルの上に、画面が上を向くように置かれているスマートフォンでは、以下の値になります。

状態 回転 Acceleration (m/s2) Acceleration with gravity (m/s2)
移動していない [0, 0, 0] [0, 0, 0] [0, 0, 9.8]
空に向かって上方向に移動 [0, 0, 0] [0, 0, 5] [0, 0, 14.81]
右方向へのみ移動 [0, 0, 0] [3, 0, 0] [3, 0, 9.81]
上方向と右方向に移動 [0, 0, 0] [5, 0, 5] [5, 0, 14.81]

以下は、携帯電話の画面が地面に対して垂直になるように保持し、ユーザーに直接画面が見える向きにした場合の値です。

状態 回転 Acceleration (m/s2) Acceleration with gravity (m/s2)
移動していない [0, 0, 0] [0, 0, 0] [0, 9.81, 0]
空に向かって上方向に移動 [0, 0, 0] [0, 5, 0] [0, 14.81, 0]
右方向へのみ移動 [0, 0, 0] [3, 0, 0] [3, 9.81, 0]
上方向と右方向に移動 [0, 0, 0] [5, 5, 0] [5, 14.81, 0]

サンプル: オブジェクトの最大加速度の計算

端末モーション イベントの 1 つの用途として、オブジェクトの最大加速度を計算することができます。 たとえば、人がジャンプする際の最大加速度を求めることも可能です。

if (evt.acceleration.x > jumpMax.x) {
  jumpMax.x = evt.acceleration.x;
}
if (evt.acceleration.y > jumpMax.y) {
  jumpMax.y = evt.acceleration.y;
}
if (evt.acceleration.z > jumpMax.z) {
  jumpMax.z = evt.acceleration.z;
}

[Go!] ボタンをタップした後、ユーザーにジャンプするよう指示します。この間、ページは最大(および最小)加速度値を記憶します。そしてジャンプの後、ユーザーに最大加速度を表示します。