Skip to content
导航

Device Orientation APIs

设备方向(Device Orientation)APIs 有两种浏览器全局事件:

  • deviceorientation
  • devicemotion

若设备不支持相关传感器,不会触发事件。

浏览器限制此API仅在HTTPS网页中可用。

deviceorientation

当设备方向传感器(陀螺仪)数据变化,浏览器会触发deviceorientation全局事件。

这个事件触发频率是有节流的,导致数值精度上有误差。例如在设备静置时稍微拨动,稳定后数值结果与上次会不同。

js
// 以下注释举例场景:手机竖向平放于桌面
window.addEventListener('deviceorientation', e=>{
  // 值一般为false,表示坐标系是相对于手机的
  const absolute = e.absolute; 

  // z 轴旋转角度,例如:手机贴桌面旋转,朝北时为0
  const alpha = e.alpha?.toFixed(1); 

  // x 轴旋转角度,例如:手机竖向抬起、放下,平放时为0
  const beta = e.beta?.toFixed(1); 

  // y 轴旋转角度,例如:手机竖向左右翻转,平放时为0
  const gamma = e.gamma?.toFixed(1); 
}, true)

由于JS数值精度问题,使用toFixed(1)避免出现很长一个小数

devicemotion

当设备加速度传感器数据变化,浏览器会触发devicemotion全局事件。

不同于deviceorientation在每个时刻是固定值,加速度是一个和时间有关的物理量。浏览器API设计为,每隔固定时间返回加速度的测量值。

js
window.addEventListener('devicemotion', e=>{
  // 设备在 X,Y,Z 轴方向上加速度的对象。加速度的单位为m/s^2
  const acceleration = e.acceleration;

  // 设备在 X,Y,Z 轴方向上带重力的加速度的对象。加速度的单位为m/s^2
  const accelerationIncludingGravity = e.accelerationIncludingGravity;

  // 设备在 alpha、beta、gamma 轴方向上旋转的速率的对象。旋转速率的单位为度每秒。
  const rotationRate = e.rotationRate;

  // 获取数据的间隔时间
  const interval = e.interval;

  console.log({
    acceleration: {
      x: acceleration?.x?.toFixed(1),
      y: acceleration?.y?.toFixed(1),
      z: acceleration?.z?.toFixed(1),
    },
    accelerationIncludingGravity: {
      x: accelerationIncludingGravity?.x?.toFixed(1),
      y: accelerationIncludingGravity?.y?.toFixed(1),
      z: accelerationIncludingGravity?.z?.toFixed(1),
    },
    rotationRate: {
      alpha: rotationRate?.alpha?.toFixed(1),
      beta: rotationRate?.beta?.toFixed(1),
      gamma: rotationRate?.gamma?.toFixed(1),
    },
    interval
  })
}, true)

由于JS数值精度问题,使用toFixed(1)避免出现很长一个小数

DEMO

兼容性

caniuse两个API的兼容性在90%左右,MDN上推荐这个polyfill解决浏览器API支持上的差异问题。这只能说明浏览器软件上支持与否。

生产环境中对这个API的使用,主要受制于硬件是否支持相关传感器。使用时总是要考虑设备不支持的情况。

参考资料