Как получить доступ к данным акселерометра / гироскопа из Javascript?


142

Недавно я наткнулся на несколько веб-сайтов, которые, похоже, обращаются к акселерометру или гироскопу на моем ноутбуке, обнаруживая изменения в ориентации или движении.

Как это сделать? Должен ли я подписаться на какое-то событие на windowобъекте?

На каких устройствах (ноутбуках, мобильных телефонах, планшетах) это работает?


NB : Я на самом деле уже знаю (частично) ответ на этот вопрос, и я собираюсь сразу его опубликовать. Причина , по которой я отправляю вопрос здесь, чтобы все остальные знают , что данные акселерометра является доступны в Javascript (на некоторых устройствах) и бросить вызов сообщества размещать новые данные по этому вопросу. В настоящее время, похоже, почти нет документации по этим функциям.


Большое усилие, большое спасибо. Считаете ли вы, что спустя 3 года ответ нуждается в каких-либо обновлениях?
Bartek Banachewicz

@BartekBanachewicz Спасибо, что позвонили мне по этому поводу. Я передам ответ в «вики сообщества», надеясь, что кто-то с более свежими знаниями обновит его, чтобы отразить текущее состояние дел.
Jørn Schou-Rode

Мне не удалось выяснить, требуется ли для этой операции согласие пользователя. Я не хотел задавать новый вопрос, так как он идеально подходит к вашему вопросу. Может, сюда добавим? Кто-нибудь знает, требуется ли для этого явное согласие? Это так во всех браузерах и всех мобильных ОС?
Silver

Ответы:


11

Способ сделать это в 2019+ - использовать DeviceOrientationAPI . Это работает в большинстве современных браузеров на ПК и мобильных устройствах.

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
}

182

В настоящее время существует три различных события, которые могут или не могут запускаться при перемещении клиентских устройств. Два из них ориентированы на ориентацию, а последний - на движение :

  • 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 используются для «согласования» показаний двух последних событий с показаниями первого, но они ни в коем случае не являются точными представлениями. Для этого простого "игрушечного" проекта он отлично работает, но если вам нужно использовать данные для чего-то более серьезного, вам придется познакомиться с единицами значений, предоставленными в различных событиях, и относиться к ним с уважением :)


9
иногда ответ просто прибивает!
Скотт Эвернден,

1
На случай, если кому-то интересно - ondevicemotion работает с Firefox 8.0, но неправильно масштабируется (0-9), но, похоже, это исправлено в более поздних версиях (10.0). Ни один из них не работает в Opera Mobile, а все стандартные нормально работают в браузере Nokia N9 по умолчанию.
Nux

2
Событие MozOrientation было удалено как устаревшее в Firefox 6. Итак, теперь все они используют стандартизированный API.
Крис Морган

Похоже, что это не работает в Firefox 30, как показано в этой скрипке . :(
bwinton

sidenote: Plax.js , который используется на страницах 404 и 500 github, использует ondeviceorientation .
Йош

22

Невозможно добавить комментарий к превосходному объяснения в другом посте , но хотелось бы отметить , что большой источник документации можно найти здесь .

Достаточно зарегистрировать функцию события для акселерометра так:

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 есть простой рабочий код


Если датчики отключены на iOS <13, window.DeviceOrientationEvent возвращает undefined?
Саврам

1

Полезный запасной вариант здесь: 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);
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.