Как создать надежный компас для 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();