如何在 Javascript 中为 iOS 和 Android 创建可靠的指南针?

Posted

技术标签:

【中文标题】如何在 Javascript 中为 iOS 和 Android 创建可靠的指南针?【英文标题】:How do I create a reliable compass for iOS and Android in Javascript? 【发布时间】:2019-01-06 15:37:35 【问题描述】:

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

这是指南针的 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 轴。对于我的测试,我把手机放在桌子上,所以只有 alpha 是相关的。

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

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

【问题讨论】:

【参考方案1】:

问题在于您的 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 中为 iOS 和 Android 创建可靠的指南针?的主要内容,如果未能解决你的问题,请参考以下文章

如何在javascript中为innerhtml添加CSS

Here Map:使用 JavaScript 在 iOS 应用程序和 Web 中为相同的起始位置和目的地绘制不同的路线

如何在IOS 11中为新的大型条设置渐变颜色的UINavigationbar?

在phonegap中为ios压缩图像插件

如何在Javascript中为1到1000的奇数和偶数编写脚本?

如何在javascript测验中为正确的选择和错误的选择着色?