Corredor

ウェブ、プログラミングの勉強メモ。

JavaScript だけでブラウザ上からスマホの向きや動きを知る … 1 DeviceOrientation 編

JavaScriptグラフィックス ―ゲーム・スマートフォン・ウェブで使う最新テクニック

JavaScriptグラフィックス ―ゲーム・スマートフォン・ウェブで使う最新テクニック

DeviceOrientationEventDeviceMotionEvent というイベント API を利用すると、JavaScript のコードだけで端末の画面の向きやモーションを知ることができる。

端末の画面の傾きや、端末がどれだけ素早く動いたかとか、そんなことを知ってどうするのかというと、主にゲームやインタラクティブな UI の構築に使えたりする。

  • 端末を横に傾けている度合いに応じて画面の要素が動く Web デザインとか
    (iPhone の壁紙の視差効果みたいなことができる)
  • モーションイベントから端末のシェイク動作を検知してデータ更新処理を呼び出すとか
    (iPhone だと「振って入力文字列の修正」ができたりするが、こういう操作に応用する)
  • 端末を勢い良く振るとゲーム内のキャラクターがジャンプする
    (今の人はゲームボーイカラーの「コロコロカービィ」ってご存知ですか…?あれもカセットに埋め込まれたジャイロセンサーによって、ゲームボーイを振るとカービィが動いたりジャンプしたりするゲームでした…)

今回は、デバイスが現在どのような向きであるかを示す DeviceOrientationEvent を取り上げて、どのように情報を取得するか紹介する。

以下の GitHub Pages にサンプルを作ったので、コチラを見ながら読んでみてほしい。

対象ブラウザがイベントを取得できるかの検知

対象のブラウザが DeviceOrientation (方位センサー) イベントを使えるかどうかは、以下の方法で確認できる。

if(DeviceOrientationEvent in window) {
  // 方位センサーが使える
}

イベント登録は window.addEventListener() で行うのだが、これに対応するイベントオブジェクトが window 配下に存在するのだ。他にも window.ondeviceorientation という window.onload 的なプロパティもいるので、これの存在確認でも良いかもしれない。

DeviceOrientationEvent の取得方法

以下のように window のイベントとして、デバイスの方向や傾きを調べることができる。

window.addEventListener('deviceorientation', function(event) {
  console.log('方角       : ' + event.alpha);
  console.log('上下の傾き : ' + event.beta);
  console.log('左右の傾き : ' + event.gamma);
  
  console.log('コンパスの向き : ' + event.webkitCompassHeading);
  console.log('コンパスの精度 : ' + event.webkitCompassAccuracy);
});
  • alpha : デバイスを縦に持った時の頭側がどちらの方角を向いているか。机の上にデバイスを置いてやると分かりやすい。0度が北。机にデバイスを置いたままデバイスを左に回転させていくと、90度で西、180度で南、270度で東となる。
  • beta : デバイスの上下の傾きを調べる。デバイスを机の上に水平に置くと0度。通常デバイスを握って垂直にした方向が90度。これとは逆にデバイスを逆さにする方向で垂直にすると-90度。
  • gamma : デバイスの左右の傾きを調べる。水平にした0度を基準に、左に回転させていくと-90度、右に回転させていくと90度。

端末を垂直にしたり、逆さまにしたりすると、値が180度入れ替わったりするので扱いには注意が必要。

iPhone の場合はさらに webkitCompassHeadingwebkitCompassAccuracy という情報もある。webkitCompassHeading は iOS 5 以降から追加されたもので、iPhone のデシタルコンパスの情報が参照できる。alpha と同様の情報が扱いやすい形で取得できる。webkitCompassAccuracy はコンパスの精度を示していて、その数値分、前後に誤差があるということ。


これで、端末が現在どのような向きを向いているかが分かるので、コンパスを作ったり、AR 的なことをやるのに使えるかと思う。

なお、このイベントは絶えず物凄い速度で呼び出されるので、console.log() を仕込んでうっかり開発者ツールを開いたりすると、物凄い量のコンソールログにヤラれるので注意。イベントに応じて何か処理を行うにしても、一定の閾値を設けて実行するなど工夫したい。

参考文献

DeviceMotion・DeviceOrientation 両方のサンプルコードが載っているサイトたち。

続編は以下。

neos21.hatenablog.com