Как получить доступ к данным акселерометра / гироскопа из Javascript? - PullRequest
128 голосов
/ 07 декабря 2010

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

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

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


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

Ответы [ 4 ]

178 голосов
/ 07 декабря 2010

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

  • ondeviceorientation, как известно, работает на настольной версии Chromeи большинство ноутбуков Apple, кажется, имеют оборудование, необходимое для этого.Он также работает на мобильном Safari на iPhone 4 с iOS 4.2.В функции обработчика событий вы можете получить доступ к значениям alpha, beta, gamma для данных события, предоставленных в качестве единственного аргумента функции.

  • onmozorientation поддерживается в Firefox 3.6 и новее.Опять же, известно, что это работает на большинстве ноутбуков Apple, но может работать и на компьютерах с Windows или Linux с акселерометром.В функции обработчика событий найдите поля x, y, z в данных события, предоставленных в качестве первого аргумента.

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

20 голосов
/ 06 октября 2014

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

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

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

имеется простой рабочий код
1 голос
/ 15 июня 2019

Способ сделать это в 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
}
1 голос
/ 02 марта 2016

Полезный запасной вариант здесь: 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);
...