检测设备方向

安全上下文:此功能仅在安全上下文(HTTPS)中可用,在某些或所有支持的浏览器中可用。

越来越多地,支持 Web 的设备能够确定其方向;也就是说,它们可以报告数据,指示其相对于重力拉力的方向变化。特别是,手机等手持设备可以使用此信息自动旋转显示屏以保持直立,在设备旋转使其宽度大于高度时,呈现 Web 内容的宽屏视图。

有两个 JavaScript 事件处理方向信息。第一个是DeviceOrientationEvent,当加速度计检测到设备方向发生变化时会发送此事件。通过接收和处理这些方向事件报告的数据,可以交互式地响应用户移动设备引起的旋转和高度变化。

第二个事件是DeviceMotionEvent,当添加加速度变化时会发送此事件。它与DeviceOrientationEvent不同,因为它侦听的是加速度变化而不是方向变化。通常能够检测DeviceMotionEvent的传感器包括笔记本电脑中用于保护移动存储设备的传感器。DeviceOrientationEvent更常见于移动设备。

处理方向事件

要开始接收方向更改,您只需侦听deviceorientation事件

js
window.addEventListener("deviceorientation", handleOrientation, true);

注册事件侦听器(在本例中,一个名为handleOrientation()的 JavaScript 函数)后,您的侦听器函数会定期使用更新的方向数据进行调用。

方向事件包含四个值

事件处理程序函数可能如下所示

js
function handleOrientation(event) {
  const absolute = event.absolute;
  const alpha = event.alpha;
  const beta = event.beta;
  const gamma = event.gamma;

  // Do stuff with the new orientation data
}

注意:视差是用于规范化移动设备上加速度计和陀螺仪数据的 polyfill。这对于克服设备方向的设备支持方面的一些差异很有用。

方向值说明

每个轴报告的值表示围绕给定轴的旋转量,相对于标准坐标系。这些在方向和运动数据说明文章中进行了更详细的描述,该文章总结如下。

  • DeviceOrientationEvent.alpha值表示设备围绕 z 轴的运动,以度为单位表示,取值范围为 0(含)到 360(不含)。
  • DeviceOrientationEvent.beta值表示设备围绕 x 轴的运动,以度为单位表示,取值范围为 -180(含)到 180(不含)。这表示设备的前后运动。
  • DeviceOrientationEvent.gamma值表示设备围绕 y 轴的运动,以度为单位表示,取值范围为 -90(含)到 90(不含)。这表示设备的左右运动。

方向示例

此示例适用于任何支持deviceorientation事件并在能够检测其方向的设备上运行的浏览器。

所以让我们想象一个花园里的球

html
<div class="garden">
  <div class="ball"></div>
</div>
Hold the device parallel to the ground. Rotate along its x and y axes to see the
ball move up/down and left/right respectively.
<pre class="output"></pre>

这个花园宽 200 像素(是的,它很小),球在中心

css
.garden {
  position: relative;
  width: 200px;
  height: 200px;
  border: 5px solid #ccc;
  border-radius: 10px;
}

.ball {
  position: absolute;
  top: 90px;
  left: 90px;
  width: 20px;
  height: 20px;
  background: green;
  border-radius: 100%;
}

现在,如果我们移动设备,球也会相应移动

js
const ball = document.querySelector(".ball");
const garden = document.querySelector(".garden");
const output = document.querySelector(".output");

const maxX = garden.clientWidth - ball.clientWidth;
const maxY = garden.clientHeight - ball.clientHeight;

function handleOrientation(event) {
  let x = event.beta; // In degree in the range [-180,180)
  let y = event.gamma; // In degree in the range [-90,90)

  output.textContent = `beta: ${x}\n`;
  output.textContent += `gamma: ${y}\n`;

  // Because we don't want to have the device upside down
  // We constrain the x value to the range [-90,90]
  if (x > 90) {
    x = 90;
  }
  if (x < -90) {
    x = -90;
  }

  // To make computation easier we shift the range of
  // x and y to [0,180]
  x += 90;
  y += 90;

  // 10 is half the size of the ball
  // It centers the positioning point to the center of the ball
  ball.style.left = `${(maxY * y) / 180 - 10}px`; // rotating device around the y axis moves the ball horizontally
  ball.style.top = `${(maxX * x) / 180 - 10}px`; // rotating device around the x axis moves the ball vertically
}

window.addEventListener("deviceorientation", handleOrientation);

点击此处在新窗口中打开此示例;因为deviceorientation并非在所有浏览器中的跨源<iframe>中都能正常工作。

处理运动事件

运动事件的处理方式与方向事件相同,只是它们有自己的事件名称:devicemotion

js
window.addEventListener("devicemotion", handleMotion, true);

真正发生变化的是作为事件侦听器参数传递的DeviceMotionEvent对象(在我们的示例中为handleMotion())中提供的信息。

运动事件包含四个属性

运动值说明

DeviceMotionEvent对象为 Web 开发人员提供了有关设备位置和方向变化速度的信息。这些变化沿三个轴提供(有关详细信息,请参阅方向和运动数据说明)。

对于accelerationaccelerationIncludingGravity,这些轴对应于以下内容

x

表示从西到东的轴

y

表示从南到北的轴

z

表示垂直于地面的轴

对于rotationRate,情况略有不同;每种情况下的信息对应于以下内容

alpha

表示沿垂直于屏幕(或台式机的键盘)的轴的旋转速率。

beta

表示沿屏幕(或台式机的键盘)平面从左到右的轴的旋转速率。

gamma

表示沿屏幕(或台式机的键盘)平面从下到上的轴的旋转速率。

最后,interval表示从设备获取数据的毫秒时间间隔。

规范

规范
设备方向和运动
# devicemotion
设备方向和运动
# deviceorientation

浏览器兼容性

api.DeviceMotionEvent

BCD 表格仅在启用 JavaScript 的浏览器中加载。

api.DeviceOrientationEvent

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅