iOS13にてjavascriptのdevicemotionを取得する

iphone向けのwebコンテンツ制作の際に、javascriptを用いてiphoneの加速度や回転速度を取得したいと思ったことが合ったのですが、iOS13ではdevicemotion, deviceorientationイベントを取得する際にちょっとした工夫が必要になります。

その方法について書き留めたいと思います。

requestPermission()関数で許可をとる

iOS13にて、devicemotion, deviceorientationを取得するためには、関数requestPermission()を用いてユーザに「動作と方向」へのアクセス可否を問う必要があります。

DeviceMotionEvent.requestPermission()
DeviceOrientationEvent.requestPermission()

上記関数をiOS13上で実行すると、以下の写真のようにユーザに「動作と方向」へのアクセス可否を問うポップアップウィンドウが表示されます。

iOS13上でjavascriptにて動作と方向へのアクセス可否を求める

使い方

iOS13以外のデバイスもアクセスすることを考慮して、以下のように使うと良いかもしれません。

<script>
function post_function( result_string ) {
    if ( result_string === "granted" ) {
        // ユーザが許可した場合、文字列"granted"が返る
    }
    else if ( result_string === "denied" ) {
// ユーザが拒否した場合、文字列"denied"が返る
    }
}

function permission_request() {
    if ( DeviceOrientationEvent
		    && DeviceOrientationEvent.requestPermission
				&& typeof DeviceOrientationEvent.requestPermission === 'function'
		) {
DeviceMotionEvent.requestPermission().then( post_function );
window.addEventListener( "devicemotion", function(e) {
            // 何らかの処理
				}, false );

    }
    if ( DeviceOrientationEvent
		    && DeviceOrientationEvent.requestPermission
				&& typeof DeviceOrientationEvent.requestPermission === 'function'
		) {
        DeviceOrientationEvent.requestPermission().then( postf_unction );
window.addEventListener( "deviceorientation", function(e) {
            // 何らかの処理
				}, false );
    }
}
</script>

<button onclick="permission_request();">動作と方向へのアクセス許可</button>

このように使います。

注意点

requestPermittion()関数によるmotionへのアクセス許可を求めるためには、ユーザがなんらかのアクションを起こす必要があります。(ボタンを設置して、そのボタンにonload=”request_permission();”を付与するなど)

例えば、以下のようなコードを実行するとエラーが吐かれます。

window.onload = function() {
    request_permission();
}
----------
Unhandled Promise Rejection: NotAllowedError: Requesting device orientation or motion access requires a user gesture to prompt

取得できる値など

DeviceMotionEvent, DeviceOrientationEventで取得できる値の代表的なものを挙げてみます。デバイスに搭載されているセンサの種類によっては、取得できずに中身がnullとなる場合もあります。

DeviceMotionEvent.acceleration
デバイスの3軸にかかる加速度[m/s2]

  • DeviceMotionEvent.acceleration.x
  • DeviceMotionEvent.acceleration.y
  • DeviceMotionEvent.acceleration.z

DeviceMotionEvent.accelerationIncludingGravity
デバイスの3軸にかかる重力加速度込みの加速度[m/s2]

  • DeviceMotionEvent.accelerationIncludingGravity.x
  • DeviceMotionEvent.accelerationIncludingGravity.y
  • DeviceMotionEvent.accelerationIncludingGravity.z

DeviceMotionEvent.rotationRate
デバイスの3軸の回転角速度[degree/s]

  • DeviceMotionEvent.acceleration.x
  • DeviceMotionEvent.acceleration.y
  • DeviceMotionEvent.acceleration.z

DeviceMotionEvent.interval
DeviceMotionEventの取得間隔[s]

motionの値は、デバイスの中心に固定されたフレーム(デバイス座標フレーム)での値を示します。
x: スクリーン水平面上。右が正、左が負。
y: スクリーン水平面上。上が正、下が負。
z: スクリーン水平面と直交。スクリーン上が正、裏側が負。

DeviceOrientationEvent
デバイスの3軸の姿勢[degree]

  • DeviceOrientationEvent.alpha
  • DeviceOrientationEvent.beta
  • DeviceOrientationEvent.gamma

orientationの値は、地球に固定されている座標フレーム(地球座標フレーム)に対する傾きを示します。
alpha: 地面と直行。すなわち、デバイスと地球中心を結ぶ線周りの傾きとなります。
beta: 地面に沿って進み、gamma座標と直行。+betaが東、-betaが西となる。
gamma: 地面に沿って進み、beta座標と直行。+gammaが北、-gammaが南。

以上、iOS13にてdevicemotion, devicecorientationを取得する方法についてでした。