检测设备方向

安全上下文: 此功能仅在安全上下文(HTTPS)中可用,且支持此功能的浏览器数量有限。

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

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

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

处理方向事件

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

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

注册事件监听器后(在本例中,是一个名为 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
}

注意: parallax 是一个 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 #cccccc;
  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);

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

运动事件包含四个属性

运动值说明

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

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

x

表示从西到东的轴

y

表示从南到北的轴

z

表示垂直于地面的轴

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

alpha

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

beta

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

gamma

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

最后,interval 表示从设备获取数据的间隔时间(以毫秒为单位)。

规范

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

浏览器兼容性

api.DeviceMotionEvent

api.DeviceOrientationEvent

另见