Как создать надежный компас для iOS и Android в Javascript?

Я пытаюсь создать надежный компас в Javascript/JQuery (используя deviceorientation), чтобы он работал на мобильных устройствах iOS и Android. Я знаю почти каждый (очень старый) вопрос / ответ здесь, в Stackru, по этой теме. Я создал довольно простой компас, который отлично работает на устройствах 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 -> приводит к описанной проблеме отклонения
  • Иначе: ориентация устройства с учетом альфа -> приводит к описанной проблеме отклонения

Я знаю, что я должен рассмотреть также бета и гамма оси. Для своих тестов я положил мобильный телефон на стол, поэтому важна только альфа.

По моим исследованиям я обнаружил очень продвинутый / полный компас javascript, упомянутый в Stackru (fulltilt-min.js), учитывающий все 3 оси. Вот демо к нему. Даже этот компас показывает мне то же неправильное направление, что и мой компас.

Так может кто-нибудь объяснить это поведение на мобильных телефонах Android или знает, как это исправить?

0 ответов

Проблема в том, что ваша альфа не абсолютна, это означает, что 0 - это не север, а 0 - это то место, куда устройство указывает при активации.

Лучший способ исправить ошибки в браузерах на основе Chrome, как и в большинстве стандартных браузеров Android, - это использовать AbsoluteOrientationSensor из полифилов W3C Generic Sensor API. 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();
Другие вопросы по тегам