16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

一部端末で方角がwebkitCompassHeadingで取得できなくなっている?ので実装した[iOS,Android]

Last updated at Posted at 2016-05-17

webkitCompassHeadingってなんぞ?

webkitCompassHeadingとは、記事「webkitCompassHeadingでSafariからでも電子コンパスの情報を取得可能。ただしiOS 5.0 以上から。」で紹介されているように、iOS 5以上のSafariで、ジャイロセンサーから方角を取得できるAPIのことです。それが**いつの間にか使えなくなっている?**ようなので、W3Cの記事「DeviceOrientation Event Specification」を見ながら実装しました。この方法なら、iOSのみならずAndroidでも方角を取得できます。

Alphaを使えばいいんじゃないの?

ジャイロセンサーにアクセスするDeviceOrientation Eventには、Alphaというパラメーターがあります。

alpha 角はデバイスの上端が地球の北極をまっすぐ向いているときが 0 度であり、デバイスが左へ回転するのに従って増加します。
方向および動きとして示されるデータより引用

リンク先を見ていただくとわかるのですが、Alphaでも方角が取得できます。それをつかえばいいじゃないか! と言いたいところですが、**GammaAlphaBetaの影響を受けるようで、Betaが90度に差し掛かると、GammaAlphaの値が一瞬180度変化してしまいます。**これだと、3D空間をジャイロセンサーとシンクロさせたい時などに、一瞬チラッと別の視線に切り替わってしまうのでマズイことになります。その回避策として、webkitCompassHeadingを使うことが多いですが、Androidで使えなかったり、サポートしているはずのiOSでも反応しなくなっているので、もうどうしたもんか状態でした :poop:

W3Cにソースコード載っていたソースコードがそのまま使えた

W3Cの記事「DeviceOrientation Event Specification|A.1 Calculating compass heading」に数式とソースコードが載っていたので試しにそのまま使ってみました。そしたら、Alphaのように影響を受けずに方角を取得できた。iOSでもAndroidでも。引数として、ジャイロセンサーのAlphaBetaGammaを渡すと0〜360度で返してくれます。

function compassHeading(alpha, beta, gamma) {
  var degtorad = Math.PI / 180; // Degree-to-Radian conversion

  var _x = beta ? beta * degtorad : 0; // beta value
  var _y = gamma ? gamma * degtorad : 0; // gamma value
  var _z = alpha ? alpha * degtorad : 0; // alpha value

  var cX = Math.cos(_x);
  var cY = Math.cos(_y);
  var cZ = Math.cos(_z);
  var sX = Math.sin(_x);
  var sY = Math.sin(_y);
  var sZ = Math.sin(_z);

  // Calculate Vx and Vy components
  var Vx = -cZ * sY - sZ * sX * cY;
  var Vy = -sZ * sY + cZ * sX * cY;

  // Calculate compass heading
  var compassHeading = Math.atan(Vx / Vy);

  // Convert compass heading to use whole unit circle
  if (Vy < 0) {
    compassHeading += Math.PI;
  } else if (Vx < 0) {
    compassHeading += 2 * Math.PI;
  }

  return compassHeading * ( 180 / Math.PI ); // Compass Heading (in degrees)
}

webkitCompassHeadingってどうなったの?

ささっと調べた限りではwebkitCompassHeadingが現状どうなっているのかよくわかりませんでした。使えなかったのは僕の手元にある端末がおかしいのか? みなさんの端末ならうまくいっているのか? 一先ず、この方法でしばらく様子を見てみたいと思います。

追記

念のために他のiOS端末で試していただきました。動いてたーーー! Android民なので、iPhoneではなくiPodで検証していたから動かなかったのか、、、? 原因ご存知のかたいらっしゃったら教えて下さい :tired_face:

16
15
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?