1. はじめに
このセクションは規範的ではありません。
この仕様は、ホストデバイスの物理的な向きや動きに関する情報を取得するための2つの新しいDOMイベントを提供します。イベントが提供する情報は生のセンサーデータではなく、情報源に依存しない高レベルのデータです。代表的な情報源にはジャイロスコープ、コンパス、加速度計などが含まれます。
deviceorientation
イベントは、デバイスの物理的な向きをローカル座標系からの一連の回転として表します。
devicemotion
イベントは、デバイスの加速度をデバイス内で定義された座標系の直交座標で表します。また、デバイスのローカル座標系まわりの回転率も提供します。可能な限り、イベントはデバイスの重心の加速度を提供すべきです。
以下のコード例はイベントの基本的な利用方法を示します。
deviceorientation
イベントを受信するための登録例:
window. addEventListener( "deviceorientation" , event=> { // event.alpha, event.beta, event.gamma を処理 }); // または... window. ondeviceorientation= event=> { // event.alpha, event.beta, event.gamma を処理 };
{ alpha: 90 , beta: 0 , gamma: 0 };
方位角を取得するには、alpha
を360度から単純に引きます。デバイスを水平面上で回転させると、方位角は (360 - alpha) となります。
devicemotion
イベントを受信するための登録例:
window. addEventListener( "devicemotion" , ( event) => { // event.acceleration, event.accelerationIncludingGravity, // event.rotationRate, event.interval を処理 }); // または... window. ondevicemotion= ( event) => { // event.acceleration, event.accelerationIncludingGravity, // event.rotationRate, event.interval を処理 };
acceleration
はゼロで、accelerationIncludingGravity
の値は以下の通りです:
{ x: 0 , y: 0 , z: 9.8 };
accelerationIncludingGravity
はゼロで、accelerationの値は以下の通りです:
{ x: 0 , y: 0 , z: - 9.8 };
acceleration
および accelerationIncludingGravity
の両方でx成分が正となります。さらに rotationRate
.gamma
の値は負となります:
{ acceleration: { x: v^ 2 / r, y: 0 , z: 0 }, accelerationIncludingGravity: { x: v^ 2 / r, y: 9.8 , z: 0 }, rotationRate: { alpha: 0 , beta: 0 , gamma: - v/ r* 180 / pi} };
2. 対象範囲
このセクションは規範的ではありません。
本仕様の対象範囲は、ホストデバイスの物理的な向きと動きを表すイベントです。範囲外となるものは、変換ライブラリのような向きデータの操作用ユーティリティや、生のセンサーデータへのアクセス、これらのセンサーへ直接インターフェースするための方法などです。
3. モデル
3.1. デバイスの向き
本仕様は、デバイスの物理的な向きを実装定義の参照座標系に対する一連の回転として表現します。
回転ステップの順序は、Z - X' - Y'' 型のイントリンジックTait-Bryan角([EULERANGLES])の組み合わせであり、 デバイス座標系([ACCELEROMETER]で定義)上で適用されます。概要は以下の通りです:
-
x は画面やキーボードの平面内で、画面やキーボードの右側方向が正です。
-
y は画面やキーボードの平面内で、画面やキーボードの上側方向が正です。
-
z は画面やキーボードに垂直で、画面やキーボードから外向きが正です。
携帯電話やタブレットなどのモバイルデバイスの場合、デバイス座標系は画面が標準の向き(通常は縦向き)にあるときの画面基準で定義されます。つまり、スライド式キーボードなどの要素は収納され、回転式ディスプレイなどは初期位置に折りたたまれています。
デバイスが回転したりスライド式キーボードが展開されたときに画面の向きが変わっても、座標系の向きはデバイス相対で変化しません。
ノートPCの場合、デバイス座標系は内蔵キーボード基準で定義されます。
注: 画面の向きの変化を検出したい場合は、[SCREEN-ORIENTATION]を参照してください。
回転は右手系規則で行われ、軸の正方向から見て時計回りが正の回転です。
注: 本仕様の座標系は、CSS Transforms
2 § 4 The Transform Rendering Modelとは異なり、y軸が下方向に正、回転は左手系規則です。
また、rotateSelf()
およびrotate()
([GEOMETRY-1]で定義)は、Z - Y' -
X''順で回転を適用します。これは本仕様とは順序が異なります。
alpha
、
beta
、
gamma
による回転は、以下の手順で行われます:
-
デバイス座標系をz軸まわりに
alpha
度回転します。alpha
の範囲は[0, 360)です。デバイスが初期位置にあり、参照(XYZ)と本体(xyz)座標系が一致している状態。 デバイスがz軸まわりにalpha度回転した状態。x軸とy軸の元の位置がx0とy0として示されています。 -
デバイス座標系をx軸まわりに
beta
度回転します。beta
の範囲は[-180, 180)です。デバイスが新しいx軸まわりにbeta度回転した状態。y軸とz軸の元の位置がy0とz0として示されています。 -
デバイス座標系をy軸まわりに
gamma
度回転します。gamma
の範囲は[-90, 90)です。デバイスが新しいy軸まわりにgamma度回転した状態。x軸とz軸の元の位置がx0とz0として示されています。
注: この角度の選択は数学的慣例に従ったものですが、alphaはコンパス方位と逆向きになります。また、これらの角度は車両ダイナミクスで使われるロール・ピッチ・ヨーの慣例とは一致しません。
3.1.1. 参照座標系の選択
デバイスの向きは常に他の座標系に対する相対位置として表現され、その選択によって向きが示す情報や向きデータの情報源が決まります。
相対デバイスの向きは加速度計とジャイロスコープで計測され、参照座標系は任意です。そのため、向きデータはデバイスの初期位置からの変化のみを示します。
注: ネイティブプラットフォームでは、これはWindowsのOrientationSensor(相対)、 Androidのgame rotation vector sensor、 あるいはCore MotionのxArbitraryZVerticalオプションに類似します。
絶対的な向きは加速度計、ジャイロスコープ、磁力計で計測され、参照座標系は地球の参照座標系です。
注: ネイティブプラットフォームでは、これはWindowsのOrientationSensor(絶対)、 Androidのrotation vector sensor、 あるいはCore MotionのxMagneticNorthZVerticalオプションに類似します。
3.2. デバイスの動き
本仕様では、加速度計とジャイロスコープから取得した加速度と回転率を計測することで、空間におけるデバイスの動きを表現します。データは前節でまとめたデバイス座標系に対して提供されます。
加速度は単位時間あたりの速度の変化率で、単位はメートル毎秒毎秒(m/s2)です。
線形デバイス加速度は重力成分を除いたデバイスの加速度率を表します。デバイスが机の上に平らに置かれている場合、線形加速度は0 m/s2です。
加速度が重力を含む場合、その値には重力の影響が含まれ、固有加速度([PROPERACCELERATION])を表します。デバイスが自由落下中の場合、加速度は0 m/s2です。これは多くの用途ではあまり有用ではありませんが、ジャイロスコープの非搭載などで線形加速度を提供できない実装に対するベストエフォートの手段です。
注: 実際には、重力を含む加速度はMotion Sensors Explainer § accelerometerや[G-FORCE]の生データに相当し、線形加速度はMotion Sensors Explainer § linear-acceleration-sensorの値であり、融合センサーである可能性が高いです。[MOTION-SENSORS]および[ACCELEROMETER]には加速度計の種類や計測可能な加速度の詳細な解説があります。
回転率は、デバイス座標系の指定軸まわりでデバイスが回転する速度を測定します。デバイスの向きと同様、回転は右手系規則であり、軸の正方向から見て時計回りが正です。回転率は毎秒の度数(deg/s)で表されます。
注: [MOTION-SENSORS]や[GYROSCOPE]にはジャイロスコープ、回転率、計測方法についての詳細な解説があります。
4. 権限
DeviceMotionEvent.requestPermission()
および DeviceOrientationEvent.requestPermission()
テストの合格率が低いためです。
本仕様は強力な機能であり、以下の権限を定義します。これらはポリシー管理機能であり、以下のデフォルト許可リストが設定されています:
-
"accelerometer"
:デフォルト許可リストは'self'です。 -
"gyroscope"
:デフォルト許可リストは'self'です。 -
"magnetometer"
:デフォルト許可リストは'self'です。
-
相対的な向きデータを提供する場合、deviceorientationイベントは、"accelerometer"と"gyroscope"の権限が許可された場合のみ発行されます。絶対的な向きデータにフォールバックするには、"magnetometer"の権限も許可されている必要があります。
-
deviceorientationabsoluteイベントは、"accelerometer"、"gyroscope"、および"magnetometer"の権限が許可された場合のみ発行されます。
-
devicemotionイベントは、"accelerometer"と"gyroscope"の権限が許可された場合のみ発行されます。
5. タスクソース
タスクソースは、本仕様で言及されているタスクのためのデバイス動き・向きタスクソースです。
6. API
6.1. deviceorientationイベント
partial interface Window { [SecureContext ]attribute EventHandler ondeviceorientation ; }; [Exposed =Window ,SecureContext ]interface :
DeviceOrientationEvent Event {(
constructor DOMString ,
type optional DeviceOrientationEventInit = {});
eventInitDict readonly attribute double ?alpha ;readonly attribute double ?beta ;readonly attribute double ?gamma ;readonly attribute boolean absolute ;static Promise <PermissionState >requestPermission (optional boolean =
absolute false ); };dictionary :
DeviceOrientationEventInit EventInit {double ?=
alpha null ;double ?=
beta null ;double ?=
gamma null ;boolean =
absolute false ; };
ondeviceorientation
属性は、イベントハンドラーIDL属性であり、
ondeviceorientation
イベントハンドラーのためのものです。そのイベントハンドラーイベントタイプはdeviceorientation
です。
alpha
属性は、初期化時の値を返すものとします。これは、§ 3.1 デバイスの向きで説明されているZ - X' -
Y''型のイントリンジックTait-Bryan角におけるZ軸まわりの回転を表します。
beta
属性は、初期化時の値を返すものとします。これは、§ 3.1 デバイスの向きで説明されている、Z軸まわりの回転が適用された後のX'軸まわりの回転を表します。
gamma
属性は、初期化時の値を返すものとします。これは、§ 3.1 デバイスの向きで説明されている、Z軸・X'軸の回転がこの順序で適用された後のY''軸まわりの回転を表します。
absolute
属性は、初期化時の値を返すものとします。これは、相対的な向き
か絶対的な向きのデータが提供されているかどうかを示します。
requestPermission(absolute)
メソッドの手順は以下の通りです:
-
globalを現在のグローバルオブジェクトとする。
-
hasTransientActivationを、thisの関連グローバルオブジェクトが一時的なアクティベーションを持つ場合はtrue、そうでなければfalseとする。
-
promiseを、新しいpromise(thisの関連Realm)とする。
-
permissionsを « "accelerometer", "gyroscope" » とする。
-
absoluteがtrueの場合、append "magnetometer" » をpermissionsに追加する。
-
以下の手順を並行して実行する:
-
各permissionsのnameについて:
-
nameの権限状態が"
prompt
" であり、hasTransientActivationがfalseの場合:-
グローバルタスクをキューに追加し、デバイス動き・向きタスクソースでglobalを指定してpromiseを"
NotAllowedError
"DOMException
でrejectする。 -
戻る。
-
-
-
permissionStateを"
granted
" とする。 -
各permissionsのnameについて:
注: 複数の権限を一度にリクエストするアルゴリズムはありませんが、ユーザーエージェントは異なるメディアへの同時リクエストを一つのユーザー向け権限プロンプトにまとめることが推奨されます。
-
権限利用のリクエストの結果が"
granted
"でない場合:
-
-
グローバルタスクをキューに追加し、デバイス動き・向きタスクソースでglobalを指定してpermissionStateでpromiseをresolveする。
-
-
promiseを返す。
DOMString
event、Window
window、boolean
absoluteが与えられた場合、以下の通りです:
-
orientationをnullとする。
-
topLevelTraversableをwindowのnavigableの最上位トラバーサブルとする。
-
virtualSensorTypeを "
relative-orientation
" (absoluteがfalseの場合)、または "absolute-orientation
" (trueの場合)とする。 -
もしtopLevelTraversableの仮想センサーマッピングがvirtualSensorTypeを含む場合:
-
virtualSensorをtopLevelTraversableの仮想センサーマッピング[virtualSensorType]とする。
-
もしvirtualSensorの読み取り可能フラグがtrueの場合:
-
orientationを、"
alpha
", "beta
", "gamma
"キー付きでvirtualSensorに提供された最新の読み取り値とする。
-
-
-
それ以外の場合:
-
permissionsをnullとする。
-
absoluteがfalseの場合:
-
permissionsを « "accelerometer", "gyroscope" » とする。
-
-
それ以外の場合:
-
permissionsを « "accelerometer", "gyroscope", "magnetometer" » とする。
-
-
environmentをwindowの関連設定オブジェクトとする。
-
以下の手順を並行して実行する:
-
各permissionsのpermissionについて:
-
stateを、現在の権限状態の取得でpermissionとenvironmentを使って取得する。
-
stateが"
granted
"でない場合、戻る。
-
-
グローバルタスクをキューに追加し、デバイス動き・向きタスクソースでwindowを指定して以下を実行:
-
zを、orientationのZ - X' - Y''型Tait-Bryan角によるZ軸方向値(実装が値を提供できない場合はnull)とする。
-
zがnullでない場合、zの精度を0.1度に制限する。
-
xを、orientationのZ - X' - Y''型Tait-Bryan角によるX'軸方向値(実装が値を提供できない場合はnull)とする。
-
xがnullでない場合、xの精度を0.1度に制限する。
-
yを、orientationのZ - X' - Y''型Tait-Bryan角によるY''軸方向値(実装が値を提供できない場合はnull)とする。
-
yがnullでない場合、yの精度を0.1度に制限する。
-
イベントを発火し、イベント名はevent、対象はwindow、型は
DeviceOrientationEvent
、alpha
属性はz、beta
属性はx、gamma
属性はy、absolute
属性はabsoluteで初期化する。
-
-
向きの重要な変化とは、前回の値と比べて、deviceorientationまたはdeviceorientationabsoluteイベントの発火に値するほどの違いがあることを示します。向きの重要な変化が発生したかどうかの判定は実装定義ですが、変化の最大閾値として1度が推奨されます。実装は、ページが十分に新鮮なデータを持っていないと考える場合にも発生したとみなしても構いません。
注: 実装は§ 9 自動化を考慮し、仮想センサーの読み取り更新によって向きの重要な変化の判定が行われるようにしなければなりません。
-
documentをwindowの関連付けられたDocumentとする。
-
documentのvisibility stateが
"visible"
でない場合、戻る。 -
absoluteをfalseとする。
-
featuresを « "accelerometer", "gyroscope" » とする。
-
実装が相対的な向きを提供できない場合や、結果として得られる絶対的な向きデータがより正確な場合:
-
absoluteをtrueにする。
-
append "magnetometer"をfeaturesに追加する。
-
-
各featuresのfeatureについて:
-
documentが利用可能でない場合、戻る。
-
-
向きイベントを発火する(deviceorientation、window、absolute)。
実装が向き情報を一切提供できない場合、alpha
、
beta
およびgamma
属性はnullとし、absolute
属性はfalseとするべきです。
6.2. deviceorientationabsoluteイベント
deviceorientationabsolute
イベントおよびondeviceorientationabsolute
イベントハンドラーIDL属性は、リスクありです。理由は実装経験が限られているためです。
partial interface Window { [SecureContext ]attribute EventHandler ondeviceorientationabsolute ; };
ondeviceorientationabsolute
属性は、イベントハンドラーIDL属性であり、
ondeviceorientationabsolute
イベントハンドラーのためのものです。そのイベントハンドラーイベントタイプはdeviceorientationabsolute
です。
deviceorientationabsoluteイベントは、deviceorientationイベントと完全に類似していますが、必ず絶対的な向きデータを提供しなければなりません。
-
向きイベントを発火する(deviceorientationabsolute、window、true)。
実装が絶対的な向き情報を一切提供できない場合、イベントはalpha
、
beta
およびgamma
属性はnullとし、absolute
属性はtrueとするべきです。
6.3. devicemotionイベント
6.3.1. DeviceMotionEventAccelerationインターフェース
[Exposed =Window ,SecureContext ]interface {
DeviceMotionEventAcceleration readonly attribute double ?x ;readonly attribute double ?y ;readonly attribute double ?z ; };
DeviceMotionEventAcceleration
インターフェースは、§ 3.2 デバイスの動きで説明されているデバイスの加速度を表します。次のデータが関連付けられています:
- x軸加速度
-
デバイスのX軸方向の加速度率。nullの場合もあります。初期値はnullです。
- y軸加速度
-
デバイスのY軸方向の加速度率。nullの場合もあります。初期値はnullです。
- z軸加速度
-
デバイスのZ軸方向の加速度率。nullの場合もあります。初期値はnullです。
x
ゲッターの手順は、thisのx軸加速度の値を返すことです。
y
ゲッターの手順は、thisのy軸加速度の値を返すことです。
z
ゲッターの手順は、thisのz軸加速度の値を返すことです。
6.3.2. DeviceMotionEventRotationRateインターフェース
[Exposed =Window ,SecureContext ]interface {
DeviceMotionEventRotationRate readonly attribute double ?alpha ;readonly attribute double ?beta ;readonly attribute double ?gamma ; };
DeviceMotionEventRotationRate
インターフェースは、回転率(§ 3.2 デバイスの動き参照)を表します。次のデータが関連付けられています:
- x軸回転率
-
デバイスのX軸まわりの回転率。nullの場合もあります。初期値はnullです。
- y軸回転率
-
デバイスのY軸まわりの回転率。nullの場合もあります。初期値はnullです。
- z軸回転率
-
デバイスのZ軸まわりの回転率。nullの場合もあります。初期値はnullです。
alpha
ゲッターの手順は、thisのx軸回転率の値を返すことです。
beta
ゲッターの手順は、thisのy軸回転率の値を返すことです。
gamma
ゲッターの手順は、thisのz軸回転率の値を返すことです。
6.3.3. DeviceMotionEventインターフェース
partial interface Window { [SecureContext ]attribute EventHandler ondevicemotion ; }; [Exposed =Window ,SecureContext ]interface :
DeviceMotionEvent Event {(
constructor DOMString ,
type optional DeviceMotionEventInit = {});
eventInitDict readonly attribute DeviceMotionEventAcceleration ?acceleration ;readonly attribute DeviceMotionEventAcceleration ?accelerationIncludingGravity ;readonly attribute DeviceMotionEventRotationRate ?rotationRate ;readonly attribute double interval ;static Promise <PermissionState >requestPermission (); };dictionary {
DeviceMotionEventAccelerationInit double ?=
x null ;double ?=
y null ;double ?=
z null ; };dictionary {
DeviceMotionEventRotationRateInit double ?=
alpha null ;double ?=
beta null ;double ?=
gamma null ; };dictionary :
DeviceMotionEventInit EventInit {DeviceMotionEventAccelerationInit ;
acceleration DeviceMotionEventAccelerationInit ;
accelerationIncludingGravity DeviceMotionEventRotationRateInit ;
rotationRate double = 0; };
interval
ondevicemotion
属性は、イベントハンドラーIDL属性であり、
ondevicemotion
イベントハンドラーのためのものです。そのイベントハンドラーイベントタイプはdevicemotion
です。
acceleration
属性は、初期化された値を返すものとします。オブジェクト作成時、この属性はnullで初期化されなければなりません。これはデバイスの線形加速度を表します。
accelerationIncludingGravity
属性は、初期化された値を返すものとします。オブジェクト作成時、この属性はnullで初期化されなければなりません。これはデバイスの重力を含む加速度を表します。
rotationRate
属性は、初期化された値を返すものとします。オブジェクト作成時、この属性はnullで初期化されなければなりません。これはデバイスの回転率を表します。
interval
属性は、初期化された値を返すものとします。これは基礎となるハードウェアからデータが取得される間隔を表し、ミリ秒(ms)単位で表現される必要があります。Webアプリケーションでデータのフィルタリングを簡素化するため一定値となります。
requestPermission()
メソッドの手順は以下の通りです:
-
globalを現在のグローバルオブジェクトとする。
-
hasTransientActivationを、thisの関連グローバルオブジェクトが一時的なアクティベーションを持つ場合はtrue、そうでなければfalseとする。
-
resultを新しいpromise(thisの関連Realm)とする。
-
以下の手順を並行して実行する:
-
permissionsを « "accelerometer", "gyroscope" » とする。
-
各permissionsのnameについて:
-
nameの権限状態が"
prompt
" であり、hasTransientActivationがfalseの場合:-
グローバルタスクをキューに追加し、デバイス動き・向きタスクソースでglobalを指定してresultを"
NotAllowedError
"DOMException
でrejectする。 -
戻る。
-
-
-
permissionStateを"
granted
" とする。 -
各permissionsのnameについて:
注: 複数の権限を一度にリクエストするアルゴリズムはありませんが、ユーザーエージェントは異なるメディアへの同時リクエストを一つのユーザー向け権限プロンプトにまとめることが推奨されます。
-
権限利用のリクエストの結果が"
granted
"でない場合:
-
-
グローバルタスクをキューに追加し、デバイス動き・向きタスクソースでglobalを指定してpermissionStateでresultをresolveする。
-
-
resultを返す。
-
documentをwindowの関連付けられたDocumentとする。
-
documentのvisibility stateが"
visible
"でない場合、戻る。 -
各« "accelerometer", "gyroscope" »のpolicyについて:
-
documentがallowed to use(利用可能)でない場合、戻る。
-
-
topLevelTraversableをwindowのnavigableの最上位トラバーサブルとする。
-
platformLinearAccelerationをnullとする。
-
もしtopLevelTraversableの仮想センサーマッピングが"
linear-acceleration
"を含む場合:-
virtualSensorをtopLevelTraversableの仮想センサーマッピング["
linear-acceleration
"]とする。 -
もしvirtualSensorの読み取り可能フラグがtrueなら、platformLinearAccelerationにvirtualSensorの最新読み取り値をセットする。
-
-
それ以外で実装が線形加速度を提供可能な場合:
-
platformLinearAccelerationにデバイスの線形加速度(X、Y、Z軸)をセットする。
-
-
accelerationをnullとする。
-
platformLinearAccelerationがnullでない場合:
-
accelerationをwindowのrealmで新規作成した
DeviceMotionEventAcceleration
とする。 -
accelerationのx軸加速度にplatformLinearAccelerationのX軸値(提供できない場合はnull)をセットする。
-
accelerationのx軸加速度がnullでなければ、その精度を最大0.1 m/s2に制限する。
-
accelerationのy軸加速度にplatformLinearAccelerationのY軸値(提供できない場合はnull)をセットする。
-
accelerationのy軸加速度がnullでなければ、その精度を最大0.1 m/s2に制限する。
-
accelerationのz軸加速度にplatformLinearAccelerationのZ軸値(提供できない場合はnull)をセットする。
-
accelerationのz軸加速度がnullでなければ、その精度を最大0.1 m/s2に制限する。
-
-
platformAccelerationIncludingGravityをnullとする。
-
もしtopLevelTraversableの仮想センサーマッピングが"
accelerometer
"を含む場合:-
virtualSensorをtopLevelTraversableの仮想センサーマッピング["
accelerometer
"]とする。 -
もしvirtualSensorの読み取り可能フラグがtrueなら、platformAccelerationIncludingGravityにvirtualSensorの最新読み取り値をセットする。
-
-
それ以外で実装が重力を含む加速度を提供可能な場合:
-
platformAccelerationIncludingGravityにデバイスの線形加速度(X、Y、Z軸)をセットする。
-
-
accelerationIncludingGravityをnullとする。
-
platformAccelerationIncludingGravityがnullでない場合:
-
accelerationIncludingGravityをwindowのrealmで新規作成した
DeviceMotionEventAcceleration
とする。 -
accelerationIncludingGravityのx軸加速度にplatformAccelerationIncludingGravityのX軸値(提供できない場合はnull)をセットする。
-
accelerationIncludingGravityのx軸加速度がnullでなければ、その精度を最大0.1 m/s2に制限する。
-
accelerationIncludingGravityのy軸加速度にplatformAccelerationIncludingGravityのY軸値(提供できない場合はnull)をセットする。
-
accelerationIncludingGravityのy軸加速度がnullでなければ、その精度を最大0.1 m/s2に制限する。
-
accelerationIncludingGravityのz軸加速度にplatformAccelerationIncludingGravityのZ軸値(提供できない場合はnull)をセットする。
-
accelerationIncludingGravityのz軸加速度がnullでなければ、その精度を最大0.1 m/s2に制限する。
-
-
platformRotationRateをnullとする。
-
もしtopLevelTraversableの仮想センサーマッピングが"
gyroscope
"を含む場合:-
virtualSensorをtopLevelTraversableの仮想センサーマッピング["
gyroscope
"]とする。 -
もしvirtualSensorの読み取り可能フラグがtrueなら、platformRotationRateにvirtualSensorの最新読み取り値をセットする。
-
-
それ以外で実装が回転率を提供可能な場合:
-
platformRotationRateにデバイスの回転率(X、Y、Z軸)をセットする。
-
-
rotationRateをnullとする。
-
platformRotationRateがnullでない場合:
-
rotationRateをwindowのrealmで新規作成した
DeviceMotionEventRotationRate
とする。 -
rotationRateのx軸回転率にplatformRotationRateのX軸値(提供できない場合はnull)をセットする。
-
rotationRateのx軸回転率がnullでなければ、その精度を最大0.1 deg/sに制限する。
-
rotationRateのy軸回転率にplatformRotationRateのY軸値(提供できない場合はnull)をセットする。
-
rotationRateのy軸回転率がnullでなければ、その精度を最大0.1 deg/sに制限する。
-
rotationRateのz軸回転率にplatformRotationRateのZ軸値(提供できない場合はnull)をセットする。
-
rotationRateのz軸回転率がnullでなければ、その精度を最大0.1 deg/sに制限する。
-
-
environmentをwindowの関連設定オブジェクトとする。
-
以下の手順を並行して実行する:
-
各« "accelerometer", "gyroscope" »のpermissionについて:
-
stateを、現在の権限状態の取得でpermissionとenvironmentを使って取得する。
-
stateが"
granted
"でない場合、戻る。
-
-
グローバルタスクをキューに追加し、デバイス動き・向きタスクソースでwindowを指定して以下を実行:
-
イベントを発火し、イベント名は"devicemotion"、対象はwindow、型は
DeviceMotionEvent
、acceleration
属性はacceleration、accelerationIncludingGravity
属性はaccelerationIncludingGravity、rotationRate
属性はrotationRate、interval
属性はintervalで初期化する。
-
-
実装が動き情報を一切提供できない場合、イベントはacceleration
、
accelerationIncludingGravity
およびrotationRate
属性はnullとするべきです。
7. セキュリティとプライバシーの考慮事項
本仕様で定義されるAPIは、加速度計、ジャイロスコープ、磁力計などのハードウェアセンサーから情報を取得するために利用できます。提供されるデータは機密情報とみなされる場合があり、悪意のあるウェブページによる攻撃の対象となる可能性があります。加速度計、ジャイロスコープ、磁力計のキャリブレーション情報は、特定のセンサーハードウェアに関する永続的な詳細を明らかにすることがあります[SENSORID]。主な攻撃ベクトルは、以下のカテゴリに分類されます:
-
ユーザー入力の監視[TOUCH]
-
位置情報の追跡[INDOORPOS]
-
ユーザーの識別[FINGERPRINT]
これを踏まえ、実装ではウェブページがセンサーを使用していることを示す視覚的なインジケーターを検討することができます。さらに、本仕様はユーザーがrequestPermission()
API呼び出しを通じてデバイスの動きや向きデータを提供することに明示的に許可することを要求します。
加えて、プライバシーリスクやフィンガープリントなどの攻撃機会を最小化するため、実装は以下を必須とします:
-
イベントはnavigableのアクティブなドキュメントのvisibility stateが"
visible
"の場合にのみ発火すること -
§ 4 権限の実装により、イベントは子navigable(クロスオリジンを含むが限定されない)で、最上位トラバーサブルによって許可されている場合のみ発火すること
-
イベントはnavigableのアクティブウィンドウで、その関連設定オブジェクトがセキュアコンテキストの場合にのみ発火すること
-
属性値の精度は前節で記載した通り制限すること
これらの項目を実装することで、モバイル機器のバッテリー寿命にも良い影響を与える場合があります。
最大サンプリング周波数の制限について更なる実装経験が収集されています。
8. アクセシビリティの考慮事項
DeviceOrientationイベントは新しい入力手段を提供し、ユーザーに新しいインタラクションの可能性を開きます。できるだけ多くの人があなたの作る体験にアクセスできるよう、以下を考慮してください:
-
必要なジェスチャーを行えない人にも他の入力手段が提供されることが重要です。例として、巧緻性に課題のある方や、視線・頭部追跡入力を使う方などが含まれます。
-
ゲームの場合、代替手段としてゲームコントローラー、キーボード、マウスの入力をサポートしましょう。
-
ウェブアプリの場合、ボタン、メニューコマンド、キーボードショートカットなど、UIを提供しましょう。
-
-
ユーザーが誤った入力を元に戻せることも重要です。これは特に振戦のある方などにとって重要です。
ユーザーエージェントまたは基盤となるOSによって管理される可能性が高い2つのニーズがありますが、あなたのコンテンツやアプリが利用される方法として、これらを念頭に置くことは有益です。
-
ユーザーがジェスチャーや動き入力の利用を無効にできることが重要です。ウェブアプリは、ボタンなど適切なアクセシブルな入力手段を提供すべきです。
-
例:シェイクでアンドゥできる機能は一部の人には自然な操作ですが、振戦のある人には障壁となる場合があります。これは権限を拒否する、あるいはブラウザやOSの設定を変更することで管理でき、ウェブアプリ側で代替入力手段を提供することも重要です。
-
-
デバイスの向きがロックできることも重要です。主なユースケースは、例えばスマートフォンで非視覚的に操作する人などです。ある向きで画面上の要素配置に「筋肉記憶」を持っている場合、レイアウトが変化するとナビゲーションが困難になります。これも、通常はOSレベルで制御されます。
9. 自動化
本仕様で定義されるイベントは物理的なハードウェアの存在とその値に依存するため、テスト著者にとって課題となる場合があります。
この課題への対応として、本書は[WEBDRIVER2]の拡張コマンドと、Generic Sensor API § 9 自動化のインフラに基づいています。これは、完全に新しい独立したインフラや別の拡張コマンドを開発するよりも、2つの仕様間に大きな重複があるため選ばれました。[GENERIC-SENSOR]仕様のテストも同様の課題があり、多くの派生API(例:[GYROSCOPE])が類似の情報を取得・提供します。
本仕様は、Generic Sensor API § 9 自動化セクションのみサポートすることを要求します。インターフェースやイベント自体は要求しません。
9.1. デバイス向きの自動化
deviceorientation
イベントの自動化サポートは、加速度計・ジャイロスコープ・(オプションで)磁力計を表現する仮想センサー上に構築されています。
ユーザーエージェントがプラットフォームから取得する向きデータは、加速度計・ジャイロスコープ・(オプションで)磁力計から取得されます。動きデータとは異なり、これらの低レベルの値は§ 3.1 デバイスの向きで記述された形でオイラー角に変換されなければなりません。さらに、プラットフォームが生の加速度・回転データからこれらの変換を行う追加APIをユーザーエージェントに提供する場合もあります。
したがって、実装や自動化の利用者に対して、異なる単位系の低レベル仮想センサー経由で向き読み取り値を提供させるのではなく、本仕様で使われる形式の相対・絶対向きデータ用の仮想センサータイプを追加で定義しています。
9.1.1. 向きデータ読み取りアルゴリズムの解析
Object
parametersが与えられたとき、以下を行います:
-
alphaをparametersから"alpha"でプロパティ取得で取得する。
-
alphaが
Number
型でない場合、または値がNaN, +∞, −∞ならundefined
を返す。 -
alphaが[0, 360)の範囲でなければ
undefined
を返す。 -
betaをparametersから"beta"でプロパティ取得で取得する。
-
betaが
Number
型でない場合、または値がNaN, +∞, −∞ならundefined
を返す。 -
betaが[-180, 180)の範囲でなければ
undefined
を返す。 -
gammaをparametersから"gamma"でプロパティ取得で取得する。
-
gammaが
Number
型でない場合、または値がNaN, +∞, −∞ならundefined
を返す。 -
gammaが[-90, 90)の範囲でなければ
undefined
を返す。 -
新しい順序付きマップ«[ "alpha" → alpha, "beta" → beta, "gamma" → gamma ]»を返す。
注: 返り値は順序付きマップであり、センサー読み取り概念への依存を避けるためです。上記アルゴリズムの目的には互換性があります。
9.1.2. "absolute-orientation"仮想センサータイプ
タイプごとの仮想センサーメタデータのマップは、以下のエントリを持たなければなりません:
-
- キー
-
"
absolute-orientation
" - 値
-
仮想センサーメタデータであり、その読み取り解析アルゴリズムは向きデータ読み取り解析です。
9.1.3. "relative-orientation"仮想センサータイプ
タイプごとの仮想センサーメタデータのマップは、以下のエントリを持たなければなりません:
-
- キー
-
"
relative-orientation
" - 値
-
仮想センサーメタデータであり、その読み取り解析アルゴリズムは向きデータ読み取り解析です。
9.2. デバイス動きの自動化
ユーザーエージェントがプラットフォームから取得する動きデータは加速度計・ジャイロスコープから取得されます。本仕様は、[ACCELEROMETER]や[GYROSCOPE]仕様と共有する特定のタイプごとの仮想センサーメタデータエントリを定義します。
加速度計仮想センサーは、プラットフォームに重力を含む加速度データを提供します。線形加速度仮想センサーは、プラットフォームに線形加速度データを提供します。ジャイロスコープ仮想センサーは、プラットフォームに回転率データを提供します。
9.2.1. "accelerometer"仮想センサータイプ
タイプごとの仮想センサーメタデータのマップは、以下のエントリを持たなければなりません:
- キー
-
"
accelerometer
" - 値
-
仮想センサーメタデータであり、その読み取り解析アルゴリズムはxyz読み取り解析です。
9.2.2. "linear-acceleration"仮想センサータイプ
タイプごとの仮想センサーメタデータのマップは、以下のエントリを持たなければなりません:
- キー
-
"
linear-acceleration
" - 値
-
仮想センサーメタデータであり、その読み取り解析アルゴリズムはxyz読み取り解析です。
9.2.3. "gyroscope"仮想センサータイプ
タイプごとの仮想センサーメタデータのマップは、以下のエントリを持たなければなりません:
- キー
-
"
ジャイロスコープ仮想センサータイプ
" - 値
-
仮想センサーのメタデータであり、その読み取り解析アルゴリズムは XYZ読み取り解析です。
付録A 例
このセクションは規範的ではありません。A.1 方位角の計算例
このセクションは規範的ではありません。
以下の具体例は、DeviceOrientationイベントの利用者向けの補助を目的としています。
はじめにセクションでは、DeviceOrientationイベントを使ってデバイスを水平に持ったときに方位角を取得する例を示しました。この例では、デバイスを垂直に持ったときにユーザーが向いている方位角を判定する方法を示します。応用例としてはAR(拡張現実)システムなどがあります。
より正確には、デバイス画面に垂直で画面背面側へ伸びるベクトルの水平成分の方位角を求めたいということになります。
このベクトルvを回転後の本体座標系xyzで表すと、vは次の通りです。
vのz軸回りの回転による変換は、次の回転行列で表されます。
vのx軸回りの回転による変換は、次の回転行列で表されます。
vのy軸回りの回転による変換は、次の回転行列で表されます。
Rがデバイスの地球座標系XYZでの完全な回転行列だとすると、初期本体座標系が地球座標系に一致しているので、Rは次のようになります。
v'が地球座標系XYZでのベクトルvだとすると、初期本体座標系が地球座標系に一致しているので、v'は次のようになります。
方位角θは次式で与えられます。
ただし、βとγが両方ゼロでない場合に限ります。
上記の方位角計算は、パラメータが定義済みかつnullでなく、absolute
値を表す場合、次のJavaScriptで表現できます。
var degtorad= Math. PI/ 180 ; // 度→ラジアン変換 function compassHeading( alpha, beta, gamma) { var _x= beta? beta* degtorad: 0 ; // beta値 var _y= gamma? gamma* degtorad: 0 ; // gamma値 var _z= alpha? alpha* degtorad: 0 ; // alpha値 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); // Vx, Vy成分を計算 var Vx= - cZ* sY- sZ* sX* cY; var Vy= - sZ* sY+ cZ* sX* cY; // 方位角を計算 var compassHeading= Math. atan( Vx/ Vy); // 方位角を全周で表現 if ( Vy< 0 ) { compassHeading+= Math. PI; } else if ( Vx< 0 ) { compassHeading+= 2 * Math. PI; } return compassHeading* ( 180 / Math. PI); // 方位角(度単位) }
一貫性チェックとして、γ = 0の場合
となり、期待通りです。
また、β = 90の場合
となり、期待通りです。
A.2 デバイスの向きの別表現
このセクションは規範的ではありません。
Tait-Bryan角による向き表現は、ジンバルロック [GIMBALLOCK] のような問題を引き起こすことがあります。用途に応じて、Device Orientation値を他の回転表現に変換すると便利な場合もあります。
最初の代替的な表現は回転行列を使う方法です。上記具体例の成分回転行列を組み合わせることで、デバイス本体座標系の向きを合成回転行列として表現できます。
Rが地球座標系XYZでのデバイスの回転行列だとすると、初期本体座標系が地球座標系に一致しているので、Rは次のようになります。
absolute
値を表す場合、以下のJavaScriptで表現できます。
var degtorad= Math. PI/ 180 ; // 度→ラジアン変換 function getRotationMatrix( alpha, beta, gamma) { var _x= beta? beta* degtorad: 0 ; // beta値 var _y= gamma? gamma* degtorad: 0 ; // gamma値 var _z= alpha? alpha* degtorad: 0 ; // alpha値 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); // // ZXY回転行列の構成 // var m11= cZ* cY- sZ* sX* sY; var m12= - cX* sZ; var m13= cY* sZ* sX+ cZ* sY; var m21= cY* sZ+ cZ* sX* sY; var m22= cZ* cX; var m23= sZ* sY- cZ* cY* sX; var m31= - cX* sY; var m32= sX; var m33= cX* cY; return [ m11, m12, m13, m21, m22, m23, m31, m32, m33]; };
デバイスの向きデータのもう一つの代替表現は、四元数(Quaternion)です。[QUATERNIONS]
qが地球座標系XYZでのデバイスの単位四元数だとすると、初期本体座標系が地球座標系に一致しているので、qは次のようになります。
absolute
値かつnullでない場合、以下のJavaScriptで表現できます。
var degtorad= Math. PI/ 180 ; // 度→ラジアン変換 function getQuaternion( alpha, beta, gamma) { var _x= beta? beta* degtorad: 0 ; // beta値 var _y= gamma? gamma* degtorad: 0 ; // gamma値 var _z= alpha? alpha* degtorad: 0 ; // alpha値 var cX= Math. cos( _x/ 2 ); var cY= Math. cos( _y/ 2 ); var cZ= Math. cos( _z/ 2 ); var sX= Math. sin( _x/ 2 ); var sY= Math. sin( _y/ 2 ); var sZ= Math. sin( _z/ 2 ); // // ZXY四元数の構成 // var w= cX* cY* cZ- sX* sY* sZ; var x= sX* cY* cZ- cX* sY* sZ; var y= cX* sY* cZ+ sX* cY* sZ; var z= cX* cY* sZ+ sX* sY* cZ; return [ w, x, y, z]; }
ラグランジュの四平方定理を使って、単位四元数が正しく構成されたかを確認できます。
となり、期待通りです。
謝辞
Device Orientation and Motion仕様は、2016年8月にDeviceOrientation Event Specificationとして候補勧告として初公開され、Geolocation Working Groupによって最初に策定されました。このグループは2017年に終了し、仕様は一時的に廃止されましたが、2019年にDevices and Sensors Working Groupによって再活性化され、相互運用性、テストの自動化、プライバシー、編集面の強化(§ 10 変更点参照)など大幅な改良が行われました。
2024年にはDevices and Sensors Working GroupがWeb Applications Working Groupと連携し、仕様は共同成果物となり、発展を続けています。初期設計の議論はこのGitHubリポジトリには残されていませんが、Geolocation Working Groupのメーリングリストアーカイブで閲覧できます。
W3Cは、Lars Erik Bolstad、Dean Jackson、Claes Nilsson、George Percivall、Doug Turner、Matt Womer、Chris Dumezの貢献に感謝します。
10. 変更点
このセクションでは、レビューの参考となる主な変更点や編集上の改善点をまとめています。詳細はコミットログをご覧ください。 2016-08-18候補勧告以降の変更点:
-
Permissions Policyの統合を追加。トップレベルフレームと同一オリジンのiframeでのみイベント発火要件を廃止
-
権限リクエストのバンドルに関する実装者向け注記を追加
-
強力な機能Accelerometer、Gyroscope、Magnetometerのエクスポート
-
Permissions APIとの統合を追加。requestPermission()の利用を必須化
-
編集: APIセクションをより規範的に、dfnを増やして定義
-
編集: Device Motion Modelセクションで加速度説明の順序を整理
-
編集: デバイスの回転・動きの参照説明を更新
-
編集: イベント処理用語をより正確に、他の用語を現代化
-
編集: [SCREEN-ORIENTATION]への参照に変更(orientation change event参照を廃止)
-
編集: 「セキュリティとプライバシーの考慮事項」の要件を表現し直し
-
ユースケース・要件・例のセクションを規範的でないと明記
-
oncompassneedscalibrationイベントを削除
-
「ユーザーアクティベーションによってトリガーされる」の参照を「一時的なアクティベーション」に変更
-
イベント発火に関するDOMの表現と整合
-
DeviceMotionEventの加速度プロパティに関する注記を追加
-
座標系がCSS座標系と異なる旨の説明を追加
-
0.1度、0.1度/秒、0.1 m/s2より精密でないことを要求し、受動的フィンガープリント問題を軽減
-
IDL内のconstructor定義をWeb IDLに合わせて更新
-
インターフェースに明示的な[Exposed]属性を追加
-
IDL辞書を新しいデフォルト化の仕組みに合わせて更新
-
deviceorientationabsoluteイベントとそのondeviceorientationabsoluteイベントハンドラーIDL属性が実装経験が限られている旨を明記
-
DeviceOrientationEventとDeviceMotionEvent両方にrequestPermission() API静的操作を追加
-
ondeviceorientation, ondevicemotion, ondeviceorientationabsoluteイベントハンドラーに[SecureContext]を追加
-
全インターフェースをセキュアコンテキストに限定
-
DeviceAccelerationとDeviceRotationRateから[NoInterfaceObject]を削除
-
セキュリティとプライバシーの考慮事項を規範的に変更
-
ondeviceorientationabsoluteイベントハンドラー属性をIDLブロックに追加(従来は説明文のみ)
-
DeviceMotionEventInitの辞書メンバーから‘?’を削除
-
[Exposed=Window]拡張属性の使用