Как получить доступ к данным акселерометра / гироскопа из 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);
Luckylooke
источник