javascript - 如何在 Javascript 中为 iOS 和 Android 创建可靠的 compass ?

标签 javascript compass device-orientation deviation

我正在尝试在 Javascript/JQuery 中创建一个可靠的 compass (使用 deviceorientation),以便它可以在 iOS 和 Android 移动设备上运行。
我知道 Stackoverflow 中关于这个主题的几乎所有(非常古老的)问题/答案。我创建了一个非常简单的 compass ,它在 iOS 设备上运行良好。在 Android 设备(Galaxy S8)上,我有一个奇怪的行为:就像我每天都在测试它, compass 方向北切换到 -45/+45、90(北在东)、180(北在南)的偏移量) 或 270 度(北在西)。是的,我考虑过 compass 校准(8 位数移动,在测试前将手机围绕它的 3 个轴转动)。

这是 compass 的 Javascript 代码:

if (isIos()) // // Function in the background evaluating OS
{ 
    window.addEventListener('deviceorientation', function(event) {
        var alpha;

        // Use Webkit heading for iOS
        alpha = event.webkitCompassHeading;
        if (alpha < 0) { alpha += 360; }
        if (alpha > 360) { alpha -= 360; }

        // Calculated heading
        console.log (alpha);
    });
}
else {
    // Any other device, with Chrome browser
    if ('ondeviceorientationabsolute' in window) {
        // Chrome 50+ specific
        window.addEventListener('deviceorientationabsolute', function (event) {
            var alpha = 360 - event.alpha;
            if (alpha < 0) { alpha += 360; }
            if (alpha > 360) { alpha -= 360; }

            // Calculated heading
            console.log (alpha);
        });
    }
    else {
        window.addEventListener('deviceorientation', function (event) {
            var alpha = 180 - event.alpha;
            if (alpha < 0) {
                alpha += 360;
            }
            if (alpha > 360) {
                alpha -= 360;
            }

            // Calculated heading
            console.log (alpha);
        });
    }
}


简而言之:
  • iOS (iPhone, iPad):使用 event.webkitCompassHeading -> 工作正常
  • Chrome:使用 ondeviceorientationabsolute -> 导致描述的偏差问题
  • 否则:考虑 alpha 的设备方向 -> 导致描述的偏差问题

  • 我知道我还必须考虑 beta 和 gamma 轴。对于我的测试,我将手机放在 table 上,所以只有 alpha 是相关的。

    通过我的研究,我发现了 Stackoverflow 中提到的一个非常先进/完整的 javascript compass 。 (fulltilt-min.js) 考虑所有 3 个轴。这是demo给它。甚至这个 compass 也向我显示了与我的 compass 完全相同的错误航向。

    那么任何人都可以在 Android 手机上解释这种行为或知道如何解决这个问题吗?

    最佳答案

    问题是您的 alpha 不是绝对的,这意味着 0 不是北,而是 0 是设备在激活时指向的位置。

    修复基于 chrome 的浏览器的最佳方法,例如大多数标准 Android 浏览器,它使用 W3C 通用传感器 API polyfills 中的 AbsoluteOrientationSensor。
    Github

    我使用的项目是基于 Typescript 的。所以这是一个 typescript 示例:

    import {AbsoluteOrientationSensor} from 'motion-sensors-polyfill'
    
    const options = { frequency: 60, referenceFrame: 'device' };
            const sensor = new AbsoluteOrientationSensor(options);
            sensor.addEventListener('reading', e => {
             //this.zone.run() if you are using an Angular Project to run it in the context of the component. 
             //If you using plain Javascript, you don't need this
              this.zone.run(() => {
                var q = e.target.quaternion;
                let alpha = Math.atan2(2*q[0]*q[1] + 2*q[2]*q[3], 1 - 2*q[1]*q[1] - 2*q[2]*q[2])*(180/Math.PI);
                if(alpha < 0) alpha = 360+ alpha;
                this.rotateCompassClockwise(360 - alpha)
              })
            });
            sensor.start();
    

    关于javascript - 如何在 Javascript 中为 iOS 和 Android 创建可靠的 compass ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51593068/

    相关文章:

    java - 使用磁力计的简单 compass - Android (Java)

    ios - 使用“常规”选项卡,无法锁定 iPad 应用程序的设备方向

    javascript - Webpack 未捕获引用错误 : require is not defined after removing node_modules from bundle. js

    javascript - 无法从 nodejs/mongoose 捕获错误

    javascript - 传入的 JSON 对象不包含 client_email 字段

    Android:activity.getResources().getConfiguration().orientation 在 Samsung galaxy 设备上返回错误值

    google-maps-api-3 - 谷歌地图js API V3 : show orientation arrow on "my location marker"

    javascript - 将 vuex 状态和突变绑定(bind)到基于 TypeScript 的 Vue 中的复选框组件属性

    symfony - 单个样式表必须在 sass 目录中

    css - Compass 与 Gulp 混合