检测设备方向

实验性: 这是一项实验性技术
在将其用于生产之前,请仔细检查浏览器兼容性表格

有越来越多的基于 web 的设备能够确定它们的方向; 也就是说,它们可以报告数据以指示基于重力方向的方向改变。特别地,手持设备如手机可以利用这些信息以自动旋转屏幕,保持内容直立,当设备旋转至横屏时(宽度大于高度),提供网页内容的横屏视图。

有两种 Javascript 事件负责处理设备方向信息。第一种是DeviceOrientationEvent,它会在加速度传感器检测到设备在方向上产生变化时触发。通过处理该事件传来的数据信息,让交互式地响应用户移动设备旋转和仰角变化成为可能。

第二种是DeviceMotionEvent,它会在加速度发生改变时触发。跟DeviceOrientationEvent不同,DeviceMotionEvent监听的是相应方向上加速度的变化。传感器通常都具有监听DeviceMotionEvent的能力,包括笔记本中用于保护移动中的存储设备的传感器。DeviceOrientationEvent事件更多见于移动设备中。

处理方向(orientation)事件

要接收设备方向变化信息,只需要监听deviceorientation事件:

备注: gyronorm.js is a polyfill for normalizing the accelerometer and gyroscope data on mobile devices. This is useful for overcoming some of the differences in device support for device orientation.

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

注册完事件监听处理函数后(对应这个例子中的 handleOrientation),监听函数会定期地接收到最新的设备方向数据。

方向事件对象中包含四个值:

DeviceOrientationEvent.absolute DeviceOrientationEvent.alpha DeviceOrientationEvent.beta DeviceOrientationEvent.gamma

下面是一个事件处理函数的例子:

js
function handleOrientation(orientData) {
  var absolute = orientData.absolute;
  var alpha = orientData.alpha;
  var beta = orientData.beta;
  var gamma = orientData.gamma;

  // Do stuff with the new orientation data
}

相关值解释

关于每一个轴的记录值表示的是相对于标准的坐标系,设备在某一个给定轴上的旋转量。Orientation and motion data explained 这篇文章有更详细的描述,下面是对这篇文章的总结。

示例

这个例子会成功运行在支持检测自己方向的设备中的支持deviceorientation 事件的浏览器中。

让我们想象一下有一个球在花园中:

html
<div class="garden">
  <div class="ball"></div>
</div>

<pre class="output"></pre>

花园只有 200px 宽(很小对吧),球在中央:

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
var ball = document.querySelector(".ball");
var garden = document.querySelector(".garden");
var output = document.querySelector(".output");

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

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

  output.innerHTML = "beta : " + x + "\n";
  output.innerHTML += "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 center the positioning point to the center of the ball
  ball.style.top = (maxX * x) / 180 - 10 + "px";
  ball.style.left = (maxY * y) / 180 - 10 + "px";
}

window.addEventListener("deviceorientation", handleOrientation);

输出结果:

这里以新窗口打开此示例;因为有些浏览器中的 deviceorientation 事件不支持跨域。

警告: Chrome 和 Firefox 处理角度的机制不同,所以某些轴上的方向是相反的。

处理移动(motion)事件

移动事件的处理跟方向事件是一样的,除了他们有自己的事件名:devicemotion

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

真正不同的是做为参数传递给HandleMotion 函数的DeviceMotionEvent对象所包含的信息。

这个对象包含四个属性:

相关值解释

DeviceMotionEvent对象提供给 web 开发者设备在位置和方向上的改变速度的相关信息。这些变化信息是通过三个轴来体现的。(Orientation and motion data explained有更详细的说明。)

accelerationaccelerationIncludingGravity,都包含下面三个轴:

  • x: 西向东
  • y: 南向北
  • z: 垂直地面

对于 rotationRate ,情况有点不同;三个轴的信息对应着以下三种情况:

  • alpha: 设备沿着垂直于屏幕(对于桌面设备则是垂直于键盘)的轴的旋转速率
  • beta: 设备沿着屏幕(对于桌面设备则是键盘)左至右方向的轴的旋转速率 (桌面设备相对于键盘)
  • gamma: 设备沿着屏幕(对于桌面设备则是键盘)下至上方向的轴的旋转速率

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

规范

Specification
Device Orientation and Motion
# devicemotion
Device Orientation and Motion
# deviceorientation

浏览器兼容性

api.DeviceMotionEvent

Report problems with this compatibility data on GitHub
desktopmobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
DeviceMotionEvent
DeviceMotionEvent() constructor
acceleration
accelerationIncludingGravity
interval
requestPermission() static method
Experimental
rotationRate

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support
Experimental. Expect behavior to change in the future.

api.DeviceOrientationEvent

Report problems with this compatibility data on GitHub
desktopmobile
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
DeviceOrientationEvent
DeviceOrientationEvent() constructor
absolute
alpha
beta
gamma
requestPermission() static method
Experimental

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
No support
No support
Experimental. Expect behavior to change in the future.
See implementation notes.

参见