1. 简介
本节是非规范性的。
本规范提供了两个新的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分量。设备还记录了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 垂直于屏幕或键盘,正方向朝向屏幕或键盘的外侧。
对于手机或平板电脑等移动设备,设备坐标系相对于屏幕的标准方向定义,通常为竖屏。这意味着像键盘这样的滑出元件未展开,像显示器这样的旋转元件被折叠到默认位置。
如果设备旋转或滑出键盘时屏幕的方向发生变化,这不会影响坐标系相对于设备的方向。
对于笔记本电脑,设备坐标系相对于内置键盘定义。
注意: 开发人员希望检测屏幕方向变化可以参考[SCREEN-ORIENTATION]。
旋转使用右手定则,这意味着沿轴的正方向看时,围绕轴的正旋转是顺时针方向。
注意: 本规范使用的坐标系与CSS Transforms 2 § 4
变换渲染模型中的不同,后者的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上的游戏旋转矢量传感器,或Core Motion中的xArbitraryZVertical选项。
绝对方向 通过加速度计、陀螺仪和磁力计测量,参考坐标系是地球参考坐标系。
注意: 在本地平台术语中,这类似于Windows上的绝对OrientationSensor, Android上的旋转矢量传感器,或Core Motion中的xMagneticNorthZVertical选项。
3.2. 设备运动
本规范通过测量设备的加速度和旋转速率来表示设备在空间中的运动,这些数据通过加速度计和陀螺仪获取。数据是相对于前一节中总结的设备坐标系提供的。
加速度是设备相对于时间的速度变化率,单位是米每秒平方(m/s2)。
线性设备加速度 表示设备不受重力影响的加速度率。当设备平放在桌面上时,其线性加速度为0 m/s2。
当包含重力的加速度时,其值包含重力的影响,并表示实际加速度([PROPERACCELERATION])。当设备处于自由落体状态时,加速度为0 m/s2。这在许多应用中不太有用,但作为一种为无法提供线性加速度(例如,由于缺乏陀螺仪)的实现提供尽力支持的方式。
注意: 实际上,包含重力的加速度代表了从运动传感器解释器§ 加速度计中获取的原始读数,或[G-FORCE], 而线性加速度则提供了运动传感器解释器§ 线性加速度传感器的读数,并且可能是融合传感器。[MOTION-SENSORS] 和[ACCELEROMETER] 都包含有关可测量的不同类型加速度计和加速度的更详细讨论。
旋转速率 测量设备绕设备坐标系中指定轴的旋转速率。与设备方向一样,旋转必须使用右手定则,这意味着沿轴正方向看时,围绕轴的正旋转为顺时针方向。旋转速率以每秒度(deg/s)为单位测量。
注意: [MOTION-SENSORS] 和[GYROSCOPE] 都包含有关陀螺仪、旋转速率和测量的更详细讨论。
4. 权限
DeviceMotionEvent.requestPermission()
和DeviceOrientationEvent.requestPermission()
测试的通过率较低,因此该集成面临风险。
本规范是强大功能,因此定义了以下权限,这些权限是具有给定策略控制功能的默认允许列表:
-
在提供相对方向数据时,仅当"accelerometer"和"gyroscope" 权限已被授予时,才会分发 deviceorientation 事件。要使实现回退到绝对方向数据,"magnetometer" 权限也必须被授予。
-
只有在"accelerometer"、"gyroscope"和"magnetometer" 权限已被授予时,才会分发deviceorientationabsolute事件。
-
只有在"accelerometer"和"gyroscope" 权限已被授予时,才会分发devicemotion事件。
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
属性必须返回初始化的值。它表示围绕 Z 轴的旋转,使用在 § 3.1 设备方向 中描述的 Z - X' - Y'' 内在 Tait-Bryan 角度。
beta
属性必须返回初始化的值。它表示围绕 X' 轴的旋转(在 Z 轴旋转之后应用),使用在
§ 3.1 设备方向 中描述的 Z - X' - Y'' 内在 Tait-Bryan 角度。
gamma
属性必须返回初始化的值。它表示围绕 Y'' 轴的旋转(按照此顺序应用 Z 和 X'
轴的旋转),使用在 § 3.1 设备方向 中描述的 Z - X' - Y'' 内在 Tait-Bryan 角度。
absolute
属性必须返回初始化的值。它表示是提供 相对方向数据还是绝对方向数据。
requestPermission(absolute)
方法的步骤如下:
-
令 global 为 当前全局对象。
-
如果this 的 相关全局对象具有瞬时激活,则令 hasTransientActivation 为 true,否则为 false。
-
令 promise 为 一个新的 promise,在this 的相关领域中。
-
令 permissions 为 « "accelerometer","gyroscope" »。
-
如果 absolute 为 true,附加 "magnetometer" » 到 permissions。
-
并行执行以下步骤:
-
对每个 name 在 permissions 中:
-
如果 name 的权限状态为 "
prompt
",并且 hasTransientActivation 为 false:-
在设备运动和方向任务来源上队列一个全局任务,给定 global 来拒绝 promise,并抛出 "
NotAllowedError
"DOMException
。 -
返回。
-
-
-
令 permissionState 为 "
granted
"。 -
对每个 name 在 permissions 中:
注意: 没有同时请求多个权限的算法。但是,建议用户代理将不同类型的媒体的并发请求合并为单个用户界面权限提示。
-
在设备运动和方向任务来源上队列一个全局任务,给定 global 来解决 promise,并返回 permissionState。
-
-
返回 promise。
DOMString
的 event,Window
的 window 和 boolean
的 absolute:
-
令 orientation 为 null。
-
如果 absolute 为 false,则将 virtualSensorType 设置为 "
relative-orientation
",否则设置为 "absolute-orientation
"。 -
否则:
-
令 permissions 为 null。
-
如果 absolute 为 false:
-
将 permissions 设置为 « "accelerometer","gyroscope" »。
-
-
否则:
-
将 permissions 设置为 « "accelerometer","gyroscope","magnetometer" »。
-
-
令 environment 为 window 的 相关设置对象。
-
并行执行以下步骤:
-
对每个 permission 在 permissions 中:
-
在设备运动和方向任务来源上队列一个全局任务,给定 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 的 可见性状态 不是
"visible"
,则返回。 -
令 absolute 为 false。
-
令 features 为 « "accelerometer","gyroscope" »。
-
如果实现无法提供 相对方向,或者生成的 绝对方向 数据更准确:
-
将 absolute 设置为 true。
-
追加 "magnetometer" 到 features。
-
-
遍历 features 中的每个 feature:
-
如果 document 不被 允许使用 feature,则返回。
-
-
触发方向事件,使用 deviceorientation、window 和 absolute。
如果实现永远无法提供方向信息,则应触发事件,并将 alpha
、beta
和 gamma
属性设置为 null,并将 absolute
属性设置为 false。
6.2. deviceorientationabsolute 事件
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 ; };
The DeviceMotionEventAcceleration
接口表示设备的加速度,如 § 3.2 设备运动 中所述。它包含以下相关数据:
- x 轴加速度
-
设备沿 X 轴的加速度,或为 null。初始为 null。
- y 轴加速度
-
设备沿 Y 轴的加速度,或为 null。初始为 null。
- z 轴加速度
-
设备沿 Z 轴的加速度,或为 null。初始为 null。
The x
getter 方法返回 this 对象的 x 轴加速度。
The y
getter 方法返回 this 对象的 y 轴加速度。
The z
getter 方法返回 this 对象的 z 轴加速度。
6.3.2. DeviceMotionEventRotationRate 接口
[Exposed =Window ,SecureContext ]interface {
DeviceMotionEventRotationRate readonly attribute double ?alpha ;readonly attribute double ?beta ;readonly attribute double ?gamma ; };
The DeviceMotionEventRotationRate
接口表示设备的旋转速率,如 § 3.2 设备运动 中所述。它包含以下相关数据:
- x 轴旋转速率
-
设备绕 X 轴的旋转速率,或为 null。初始为 null。
- y 轴旋转速率
-
设备绕 Y 轴的旋转速率,或为 null。初始为 null。
- z 轴旋转速率
-
设备绕 Z 轴的旋转速率,或为 null。初始为 null。
The alpha
getter 方法返回 this 对象的 x 轴旋转速率。
The beta
getter 方法返回 this 对象的 y 轴旋转速率。
The gamma
getter 方法返回 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 为 当前全局对象。
-
令 result 为 一个新的 promise,位于 this 的 相关 Realm 中。
-
并行执行这些步骤 in parallel:
-
令 permissions 为 « "accelerometer", "gyroscope" »。
-
对于 permissions 中的每个 name:
-
如果 name 的 权限状态 为 "
prompt
" 且 hasTransientActivation 为 false:-
在 设备运动与方向任务源 上排队一个全局任务,给定 global 来 拒绝 result,并返回 "
NotAllowedError
"DOMException
。 -
返回。
-
-
-
将 permissionState 设为 "
granted
"。 -
对于 permissions 中的每个 name:
注意: 没有一次请求多个权限的算法。然而,鼓励用户代理将不同种类的媒体的并发请求捆绑为单个用户界面的权限请求。
-
在 设备运动与方向任务源 上排队一个全局任务,给定 global 来 解决 result 并返回 permissionState。
-
-
返回 result。
-
令 document 为 window 的 关联的文档。
-
如果 document 的 可见性状态 不是 "
visible
",则返回。 -
对于每个 « "accelerometer", "gyroscope" » 中的策略:
-
令 platformLinearAcceleration 为 null。
-
否则,如果实现能够提供 线性加速度:
-
将 platformLinearAcceleration 设置为设备沿 X、Y 和 Z 轴的 线性加速度。
-
-
令 acceleration 为 null。
-
如果 platformLinearAcceleration 不为 null:
-
将 acceleration 设置为一个 新的
DeviceMotionEventAcceleration
在 window 的 realm 中创建。 -
将 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。
-
否则,如果实现能够提供 带重力的加速度:
-
将 platformAccelerationIncludingGravity 设置为设备沿 X、Y 和 Z 轴的 线性加速度。
-
-
令 accelerationIncludingGravity 为 null。
-
如果 platformAccelerationIncludingGravity 不为 null:
-
将 accelerationIncludingGravity 设置为一个 新的
DeviceMotionEventAcceleration
在 window 的 realm 中创建。 -
将 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。
-
否则,如果实现能够提供 旋转速率:
-
将 platformRotationRate 设置为设备沿 X、Y 和 Z 轴的 旋转速率。
-
-
令 rotationRate 为 null。
-
如果 platformRotationRate 不为 null:
-
将 rotationRate 设置为一个 新的
DeviceMotionEventRotationRate
在 window 的 realm 中创建。 -
将 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 的 相关设置对象。
-
并行执行这些步骤 in parallel:
-
对于 « "accelerometer", "gyroscope" » 中的每个 permission:
-
给定 window,在设备运动和方向任务源上排队一个全局任务,以运行以下步骤:
-
在 window 上使用
DeviceMotionEvent
触发一个名为 "devicemotion" 的事件,其中acceleration
属性初始化为 acceleration,accelerationIncludingGravity
属性初始化为 accelerationIncludingGravity,rotationRate
属性初始化为 rotationRate,并且interval
属性初始化为 interval。
-
-
如果实现永远无法提供运动信息,则应触发该事件,acceleration
、
accelerationIncludingGravity
和 rotationRate
属性应设置为 null。
7. 安全和隐私注意事项
本规范中定义的 API 可以用于从硬件传感器(如加速度计、陀螺仪和磁力计)获取信息。提供的数据可能被视为敏感信息,可能成为恶意网页攻击的目标。加速度计、陀螺仪和磁力计的校准可能暴露有关特定传感器硬件的持久性细节 [SENSORID]。主要的攻击向量可以分为以下几类:
-
监视用户输入 [TOUCH]
-
位置跟踪 [INDOORPOS]
-
用户识别 [FINGERPRINT]
鉴于此,实施过程中可以考虑通过视觉指示器标示网页使用传感器的情况。此外,本规范要求用户通过 明确许可 来允许用户代理通过 requestPermission()
API
调用提供设备运动和/或方向数据。
此外,为了最小化隐私风险,减少指纹识别和其他攻击的可能性,实施必须:
-
限制属性值的精度,如前几节所述。
此外,实施这些项可能对移动设备的电池寿命产生积极影响。
进一步的实施经验 正在收集中,以确定最大采样频率的上限。
8. 可访问性注意事项
DeviceOrientation 事件提供了新的输入形式的机会,这可以为用户带来新的交互方式。为了确保尽可能多的人能够与您构建的体验进行交互,请考虑以下事项:
-
重要的是提供替代的输入方式,以便那些无法执行所需手势的人可以通过其他方式进行交互。例如,患有灵活性相关障碍的人,或使用眼动仪、头部跟踪输入设备的人。
-
对于游戏,考虑支持游戏控制器、键盘或鼠标输入作为替代交互方式。
-
对于 Web 应用,考虑提供 UI,如按钮、菜单命令和/或键盘快捷键来执行功能。
-
-
确保用户能够撤销任何意外输入,这对有颤抖症状的人特别重要。
有两个用户需求可能会出现,通常由用户代理或底层操作系统管理。然而,考虑这些因素可能有助于您了解内容或应用的使用方式。
-
用户应能够禁用手势或基于运动的输入。Web 应用应提供适当的可访问手段让用户输入这些内容,如按钮。
-
例如:摇动撤销功能对一些人来说是一种自然且周到的交互方式,但对有颤抖症状的人来说,这可能是一个障碍。这可以通过拒绝许可或更可能通过更改浏览器或操作系统设置并结合 Web 应用提供替代输入方式来解决。
-
-
设备的方向应能够锁定——一个主要的用例是盲人或低视力用户在与触控设备(如手机)交互时,他们可能已经形成了对某个方向上屏幕元素位置的“肌肉记忆”,布局的改变会破坏他们的导航能力。这通常是由操作系统级别完成的。
9. 自动化
本规范可能给测试作者带来挑战,因为这里定义的事件依赖于物理硬件的存在,而硬件读数无法轻易控制。
为了解决这一挑战,本文档基于 [WEBDRIVER2] 扩展命令 和 通用传感器 API § 9 自动化 所制定的基础设施。这种方式被优先选择,而不是开发全新的独立基础设施,因为这两个规范之间存在显著重叠:不仅是测试 [GENERIC-SENSOR] 规范面临类似的挑战,许多派生的 API(例如 [GYROSCOPE])获取并提供了类似的信息。
本规范只要求实现支持 通用传感器 API § 9 自动化 章节,而不要求其接口和事件。
9.1. 设备方向自动化
对 deviceorientation
事件的自动化支持建立在表示加速度计、陀螺仪和(可选的)磁力计的虚拟传感器之上。
用户代理从平台获取的方向数据来自加速度计、陀螺仪和(可选的)磁力计。与运动数据不同的是,这些低级读数必须转换为 § 3.1 设备方向 中描述的欧拉角。此外,平台可能会为用户代理提供额外的 API,这些 API 已经执行了从原始加速度和旋转数据到欧拉角的部分转换。
因此,本规范定义了额外的 虚拟传感器类型,用于相对和方向数据的格式,而不是要求实现和自动化用户通过使用不同计量单位的低级虚拟传感器来提供方向读数。
9.1.1. 解析方向读数数据算法
Object
parameters:
-
从 parameters 中通过 "alpha" 调用 获取属性,并将结果赋值给 alpha。
-
如果 alpha 不是一个
数字
, 或其值为 NaN、+∞ 或 −∞,则返回undefined
。 -
如果 alpha 不在 [0, 360) 范围内,则返回
undefined
。 -
从 parameters 中通过 "beta" 调用 获取属性,并将结果赋值给 beta。
-
如果 beta 不是一个
数字
, 或其值为 NaN、+∞ 或 −∞,则返回undefined
。 -
如果 beta 不在 [-180, 180) 范围内,则返回
undefined
。 -
从 parameters 中通过 "gamma" 调用 获取属性,并将结果赋值给 gamma。
-
如果 gamma 不是一个
数字
, 或其值为 NaN、+∞ 或 −∞,则返回undefined
。 -
如果 gamma 不在 [-90, 90) 范围内,则返回
undefined
。 -
返回一个新的 有序映射 «[ "alpha" → alpha, "beta" → beta, "gamma" → gamma ]»。
注意: 返回值是一个 有序映射,以避免依赖 传感器读数 的概念,来自 [GENERIC-SENSOR] 规范。对于上述算法的目的,它们应该是可互换的。
9.1.2. "absolute-orientation" 虚拟传感器类型
每种类型的虚拟传感器元数据 元数据 映射 必须包含以下 条目:
9.1.3. "relative-orientation" 虚拟传感器类型
每种类型的虚拟传感器元数据 元数据 映射 必须包含以下 条目:
9.2. 设备运动自动化
用户代理从平台获取的运动数据来自加速度计和陀螺仪。本规范定义了与 [ACCELEROMETER] 和 [GYROSCOPE] 规范共享的某些 每种类型的虚拟传感器元数据 条目。
加速度计虚拟传感器用于向平台提供 带重力的加速度 数据。线性加速度虚拟传感器用于向平台提供 线性加速度 数据。陀螺仪虚拟传感器用于向平台提供 旋转速率 数据。
9.2.1. "accelerometer" 虚拟传感器类型
每种类型的虚拟传感器元数据 元数据 映射 必须包含以下 条目:
9.2.2. "linear-acceleration" 虚拟传感器类型
每种类型的虚拟传感器元数据 元数据 映射 必须包含以下 条目:
9.2.3. "gyroscope" 虚拟传感器类型
每种类型的虚拟传感器元数据 元数据 映射 必须包含以下 条目:
A 示例
本节非规范性。A.1 计算指南针方向
本节非规范性。
以下示例旨在帮助用户理解 DeviceOrientation 事件的使用。
简介 部分提供了一个使用 DeviceOrientation 事件在设备水平持有时获取指南针方向的示例。该示例展示了如何在设备屏幕垂直朝向用户时,确定用户面对的指南针方向。这一应用的例子可以是增强现实系统。
更准确地说,我们希望确定一个与设备屏幕垂直并指向屏幕后方的向量的水平分量的指南针方向。
如果 v 表示在旋转的设备体坐标系 xyz 中的该向量,则 v 如下所示。
绕 z 轴旋转引起的 v 的变换可以通过以下旋转矩阵表示。
绕 x 轴旋转引起的 v 的变换可以通过以下旋转矩阵表示。
绕 y 轴旋转引起的 v 的变换可以通过以下旋转矩阵表示。
如果 R 表示设备在地球坐标系 XYZ 中的完整旋转矩阵,则由于初始体坐标系与地球对齐,R 如下所示。
如果 v' 表示在地球坐标系 XYZ 中的向量 v,则由于初始体坐标系与地球对齐,v' 如下所示。
指南针方向 θ 如下所示
前提是 β 和 γ 都不为零。
上面的指南针方向计算可以通过以下 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 替代设备方向表示法
本节非规范性。
使用泰特-布莱恩角描述方向可能存在一些缺点,例如引入万向节锁[GIMBALLOCK]。根据具体应用的不同,将设备方向值转换为其他旋转表示可能会更有用。
第一种替代方向表示法使用旋转矩阵。通过结合上面示例中提供的分量旋转矩阵,我们可以将设备体坐标系的方向表示为一个组合旋转矩阵。
如果 R 表示设备在地球坐标系 XYZ 中的旋转矩阵,那么由于初始体坐标系与地球对齐,R 如下所示。
绝对
值。
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]; };
设备方向数据的另一种替代表示法是四元数[QUATERNIONS]。
如果 q 表示设备在地球坐标系 XYZ 中的单位四元数,那么由于初始体坐标系与地球对齐,q 如下所示。
绝对
值且这些参数不为 null。
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 和 Motion 规范最初于 2016 年 8 月作为候选推荐标准发布,标题为 DeviceOrientation Event Specification,最初由Geolocation 工作组开发。该组于 2017 年关闭后,该规范被暂时搁置。2019 年,由设备与传感器工作组重新启动,本文件进行了重大改进,包括互操作性、测试自动化、隐私和编辑内容的增强(见§ 10 变更部分)。
2024 年,设备与传感器工作组与Web 应用工作组合作,使这一规范成为共同成果,并继续推进该规范的制定。最初的设计讨论保存在此 GitHub 仓库中,但可以通过Geolocation 工作组的邮件列表归档进行探索。
W3C 感谢 Lars Erik Bolstad、Dean Jackson、Claes Nilsson、George Percivall、Doug Turner、Matt Womer 和 Chris Dumez 的贡献。
10. 变更
本节总结了重要的变更和显著的编辑改进,以便进行审查。完整详细信息请参阅提交日志。自候选推荐标准 2016-08-18以来的变更如下:
-
添加权限策略集成,取代了之前只允许在与顶级框架同源的 iframe 上触发事件的要求
-
添加关于捆绑权限请求的实施者注释
-
导出强大功能:加速度计、陀螺仪和磁力计
-
添加权限 API 集成,开始要求使用 requestPermission()
-
编辑改进:更规范地定义 API 部分,并添加更多的定义
-
编辑改进:重新排列设备运动模型部分中的加速度说明
-
编辑改进:更新设备旋转和运动参考的解释
-
编辑改进:使用更精确的事件处理术语,现代化其他术语
-
编辑改进:参考[SCREEN-ORIENTATION],而不是方向变化事件
-
编辑改进:重新表述“安全和隐私考虑”中的要求
-
标记用例和要求以及示例部分为非规范性
-
移除 oncompassneedscalibration 事件
-
更新对“用户激活触发”的引用,现在称为“瞬态激活”
-
与 DOM 术语保持一致,调整触发事件的表述
-
为 DeviceMotionEvent 添加关于加速度属性的注释
-
添加注释解释坐标系与 CSS 坐标系的不同之处
-
要求精度不超过 0.1 度、0.1 度/秒、0.1 米/秒²,以减轻被动指纹识别问题
-
使用 Web IDL 更新构造函数定义
-
为接口添加显式 [Exposed]
-
使用新的字典默认设置更新 IDL 字典
-
注明 deviceorientationabsolute 事件及其 ondeviceorientationabsolute 事件处理程序 IDL 属性的有限实现经验
-
为 DeviceOrientationEvent 和 DeviceMotionEvent 添加 requestPermission() API 静态操作
-
为 ondeviceorientation、ondevicemotion 和 ondeviceorientationabsolute 事件处理程序添加 [SecureContext]
-
将所有接口限制为安全上下文
-
从 DeviceAcceleration 和 DeviceRotationRate 中移除 [NoInterfaceObject]
-
使安全和隐私考虑部分成为规范性内容
-
将 ondeviceorientationabsolute 事件处理程序属性添加到 IDL 块中(之前只在正文中)
-
从 DeviceMotionEventInit 的字典成员中移除 '?' 符号
-
使用 [Exposed=Window] 扩展属性