Как получить доступ к данным акселерометра/гироскопа из Javascript?
Недавно я познакомился с несколькими веб-сайтами, которые, похоже, обращаются к акселерометру или гироскопу на моем ноутбуке, обнаруживая изменения в ориентации или движении.
Как это делается? Должен ли я подписаться на какое-то событие в объекте window
?
На каких устройствах (ноутбуках, мобильных телефонах, планшетах) известно, что они работают?
NB. Я уже знаю (часть) ответа на этот вопрос, и я собираюсь опубликовать его сразу. Причина, по которой я размещаю этот вопрос, заключается в том, чтобы позволить всем остальным узнать, что данные акселерометра доступны в Javascript (на некоторых устройствах) и оспорить сообщество опубликовать новые выводы по этому вопросу. В настоящее время, похоже, почти нет документации этих функций.
Ответы
Ответ 1
В настоящее время существует три различных события, которые могут срабатывать или не запускаться при перемещении клиентских устройств. Два из них сосредоточены вокруг ориентации и последние в движении:
-
Известно, что
-
ondeviceorientation
работает с настольной версией Chrome, и большинство ноутбуков Apple, похоже, имеют необходимое для этого оборудование. Он также работает на Mobile Safari на iPhone 4 с iOS 4.2. В функции обработчика событий вы можете получить доступ к значениям alpha
, beta
, gamma
в данных события, предоставленных в качестве единственного аргумента функции.
-
onmozorientation
поддерживается в Firefox 3.6 и новее. Опять же, это, как известно, работает на большинстве ноутбуков Apple, но может работать и на машинах Windows или Linux с акселерометром. В функции обработчика событий найдите поля x
, y
, z
в данных события, предоставленных в качестве первого аргумента.
Известно, что -
ondevicemotion
работает на iPhone 3GS + 4 и iPad (как с iOS 4.2), так и предоставляет данные, связанные с текущим ускорением клиентского устройства. Данные события, переданные функции обработчика, имеют acceleration
и accelerationIncludingGravity
, которые имеют по три поля для каждой оси: x
, y
, z
На веб-сайте примера "обнаружение землетрясений" используется серия операторов 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 используются для "выравнивания" показаний двух последних событий с данными из первого, но это далеко не точное представление. Для этого простого "игрушечного" проекта он работает отлично, но если вам нужно использовать данные для чего-то более серьезного, вам нужно будет ознакомиться с единицами значений, представленных в разных событиях, и относиться к ним с уважением:)
Ответ 2
Не могу добавить комментарий к отличному объяснению в другом посте, но хотел бы отметить, что отличный источник документации можно найти здесь.
Для акселерометра достаточно зарегистрировать функцию события:
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
);
}
Есть также поля, указанные в событии движения для гироскопа, но это, кажется, не поддерживается повсеместно (например, это не работает на Samsung Galaxy Note).
На GitHub есть простой рабочий код
Ответ 3
Полезный резерв здесь: 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);
Ответ 4
Способ сделать это в 2019+ - использовать DeviceOrientation
API. Это работает в большинстве современных браузеров на настольных и мобильных устройствах.
window.addEventListener("deviceorientation", handleOrientation, true);
После регистрации прослушивателя событий (в данном случае JavaScript-функции handleOrientation()) функция прослушивателя периодически вызывается с обновленными данными об ориентации.
Событие ориентации содержит четыре значения:
-
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
}