如何从 Javascript 访问加速度计/陀螺仪数据?

IT技术 javascript accelerometer gyroscope
2021-01-13 19:59:29

我最近发现一些网站似乎可以访问我笔记本电脑上的加速度计或陀螺仪,检测方向或运动的变化。

这是怎么做的?我必须订阅window对象上的某种事件吗?

已知可以在哪些设备(笔记本电脑、手机、平板电脑)上使用?


注意:我实际上已经知道(部分)这个问题的答案,我将立即发布。我在这里张贴问题的原因,是为了让每个人都知道,加速度计数据在Javascript中可用的(在某些设备上),并挑战社会关于这个问题发表新的研究结果。目前,似乎几乎没有这些功能的文档。

4个回答

当前存在三个不同的事件,它们可能会或可能不会在客户端设备移动时被触发。其中两个关注方向,最后一个关注运动

  • ondeviceorientation已知可以在桌面版 Chrome 上运行,并且大多数 Apple 笔记本电脑似乎都具有运行所需的硬件。它也适用于装有 iOS 4.2 的 iPhone 4 上的 Mobile Safari。在事件处理函数中,您可以访问作为函数唯一参数提供的事件数据的alpha, beta,gamma值。

  • onmozorientationFirefox 3.6 及更新版本支持。同样,众所周知,这适用于大多数 Apple 笔记本电脑,但也可能适用于带有加速度计的 Windows 或 Linux 机器。在事件处理函数中,在作为第一个参数提供的事件数据上查找x, y,z字段。

  • ondevicemotion已知适用于 iPhone 3GS + 4 和 iPad(均使用 iOS 4.2),并提供与客户端设备当前加速相关的数据。传递给处理函数的事件数据有accelerationaccelerationIncludingGravity,每个轴都有三个字段:xyz

“地震检测”示例网站使用一系列if语句来确定要附加到哪个事件(以某种优先顺序)并将接收到的数据传递给一个通用tilt函数:

if (window.DeviceOrientationEvent) {
    window.addEventListener("deviceorientation", function () {
        tilt([event.beta, event.gamma]);
    }, true);
} else if (window.DeviceMotionEvent) {
    window.addEventListener('devicemotion', function () {
        tilt([event.acceleration.x * 2, event.acceleration.y * 2]);
    }, true);
} else {
    window.addEventListener("MozOrientation", function () {
        tilt([orientation.x * 50, orientation.y * 50]);
    }, true);
}

常数因子 2 和 50 用于将后两个事件的读数与第一个事件的读数“对齐”,但这绝不是精确的表示。对于这个简单的“玩具”项目,它工作得很好,但是如果您需要将数据用于更严重的事情,您将必须熟悉不同事件中提供的值的单位并尊重它们:)

有时一个答案就是钉钉!
2021-03-16 19:59:29
MozOrientation 事件在 Firefox 6 中被删除为过时。所以现在他们都使用标准化的 API。
2021-03-16 19:59:29
旁注:Plax.js,这是在GitHub的404个500页上使用,使用ondeviceorientation
2021-03-24 19:59:29
如果有人想知道 - ondevicemotion 适用于 Firefox 8.0,但缩放错误 (0-9),但这似乎在更高版本 (10.0) 中得到修复。它们都不适用于 Opera Mobile,所有标准的都适用于默认的诺基亚 N9 浏览器。
2021-04-04 19:59:29
这在 Firefox 30 中似乎不起作用,如这个 fiddle所示:(
2021-04-13 19:59:29

无法在另一篇文章中对出色的解释添加评论,但想提一下可以在这里找到一个很好的文档来源

为加速度计注册一个事件函数就足够了,如下所示:

if(window.DeviceMotionEvent){
  window.addEventListener("devicemotion", motion, false);
}else{
  console.log("DeviceMotionEvent is not supported");
}

与处理程序:

function motion(event){
  console.log("Accelerometer: "
    + event.accelerationIncludingGravity.x + ", "
    + event.accelerationIncludingGravity.y + ", "
    + event.accelerationIncludingGravity.z
  );
}

对于磁力计,必须注册以下事件处理程序:

if(window.DeviceOrientationEvent){
  window.addEventListener("deviceorientation", orientation, false);
}else{
  console.log("DeviceOrientationEvent is not supported");
}

带有处理程序:

function orientation(event){
  console.log("Magnetometer: "
    + event.alpha + ", "
    + event.beta + ", "
    + event.gamma
  );
}

在陀螺仪的运动事件中还指定了一些字段,但这似乎并未得到普遍支持(例如,它不适用于三星 Galaxy Note)。

GitHub 上有一个简单的工作代码

如果传感器在 iOS < 13 上被禁用,window.DeviceOrientationEvent 返回 undefined?
2021-03-21 19:59:29

在 2019+ 中做到这一点的方法是使用DeviceOrientationAPI这适用于桌面和移动设备上的大多数现代浏览器

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

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

方向事件包含四个值:

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

事件处理函数看起来像这样:

function handleOrientation(event) {
  var absolute = event.absolute;
  var alpha    = event.alpha;
  var beta     = event.beta;
  var gamma    = event.gamma;
  // Do stuff with the new orientation data
}

有用的回退:https : //developer.mozilla.org/en-US/docs/Web/Events/MozOrientation

function orientationhandler(evt){


  // For FF3.6+
  if (!evt.gamma && !evt.beta) {
    evt.gamma = -(evt.x * (180 / Math.PI));
    evt.beta = -(evt.y * (180 / Math.PI));
  }

  // use evt.gamma, evt.beta, and evt.alpha 
  // according to dev.w3.org/geo/api/spec-source-orientation


}

window.addEventListener('deviceorientation',  orientationhandler, false);
window.addEventListener('MozOrientation',     orientationhandler, false);