Jak uzyskać dostęp do danych akcelerometru / żyroskopu z JavaScript?

139

Niedawno natknąłem się na kilka witryn, które wydają się mieć dostęp do akcelerometru lub żyroskopu w moim laptopie, wykrywając zmiany orientacji lub ruchu.

Jak to się robi? Czy muszę zapisać się na jakieś wydarzenie nawindow obiekcie?

Na jakich urządzeniach (laptopach, telefonach komórkowych, tabletach) to działa?


NB : Właściwie znam już (część) odpowiedź na to pytanie i zaraz ją opublikuję. Powodem, dla którego zadaję to pytanie, jest poinformowanie wszystkich innych, że dane akcelerometru dostępne w Javascript (na niektórych urządzeniach) i wezwanie społeczności do opublikowania nowych odkryć na ten temat. Obecnie wydaje się, że prawie nie ma dokumentacji dotyczącej tych funkcji.

Jørn Schou-Rode
źródło
Wielkie wysiłki, wielkie dzięki. Czy uważasz, że 3 lata później odpowiedź wymaga aktualizacji?
Bartek Banachewicz
@BartekBanachewicz Dzięki za wezwanie mnie w tej sprawie. Prześlę odpowiedź na „wiki społeczności”, mając nadzieję, że ktoś z bardziej aktualną wiedzą zaktualizuje ją tak, aby odzwierciedlała aktualny stan wiedzy.
Jørn Schou-Rode
Nie mogłem znaleźć, czy ta operacja wymaga zgody użytkownika. Nie chciałem zadawać nowego pytania, ponieważ idealnie pasuje do twojego pytania. Może możemy to dodać tutaj? Czy ktoś wie, czy wymaga to wyraźnej zgody? Czy tak jest we wszystkich przeglądarkach i wszystkich mobilnych systemach operacyjnych?
Srebro

Odpowiedzi:

8

Sposobem na to w 2019+ jest użycie DeviceOrientationAPI . Działa to w większości nowoczesnych przeglądarek na komputerach stacjonarnych i urządzeniach mobilnych.

window.addEventListener("deviceorientation", handleOrientation, true);

Po zarejestrowaniu detektora zdarzeń (w tym przypadku funkcji JavaScript o nazwie handleOrientation ()), funkcja detektora jest okresowo wywoływana ze zaktualizowanymi danymi orientacji.

Wydarzenie orientacyjne zawiera cztery wartości:

  • DeviceOrientationEvent.absolute
  • DeviceOrientationEvent.alpha
  • DeviceOrientationEvent.beta
  • DeviceOrientationEvent.gamma

Funkcja obsługi zdarzeń może wyglądać mniej więcej tak:

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
}
str
źródło
179

Obecnie istnieją trzy różne zdarzenia, które mogą, ale nie muszą, zostać wyzwolone podczas przenoszenia urządzeń klienckich. Dwie z nich koncentrują się na orientacji, a ostatnia na ruchu :

  • ondeviceorientationwiadomo, że działa na komputerowej wersji Chrome, a większość laptopów Apple wydaje się mieć sprzęt wymagany do tego. Działa również w Mobile Safari na iPhonie 4 z iOS 4.2. W funkcji obsługi zdarzeń, można uzyskać dostęp alpha, beta, gammawartości na podstawie danych o zdarzeniach, dostarczanych jako jedyny argument funkcji.

  • onmozorientationjest obsługiwany w przeglądarce Firefox 3.6 i nowszych. Ponownie, wiadomo, że działa to na większości laptopów Apple, ale może działać również na komputerach z systemem Windows lub Linux z akcelerometrem. W funkcji obsługi zdarzenia, szukać x, y, zpola dotyczące danych o zdarzeniach dostarczane jako pierwszy argument.

  • ondevicemotiondziała na iPhonie 3GS + 4 i iPadzie (oba z iOS 4.2) i dostarcza danych związanych z aktualnym przyspieszeniem urządzenia klienckiego. Dane zdarzeń przekazywane do funkcji obsługi ma accelerationi accelerationIncludingGravity, które oba mają trzy pola dla każdej osi: x, y,z

Przykładowa witryna internetowa „wykrywanie trzęsień ziemi” wykorzystuje serię ifinstrukcji, aby ustalić, do którego zdarzenia należy się dołączyć (w nieco uporządkowanej kolejności) i przekazuje otrzymane dane do wspólnej tiltfunkcji:

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);
}

Stałe współczynniki 2 i 50 służą do „wyrównania” odczytów z dwóch ostatnich wydarzeń z odczytami z pierwszego, ale nie są to bynajmniej dokładne reprezentacje. W przypadku tego prostego projektu "zabawki" działa to dobrze, ale jeśli chcesz wykorzystać dane do czegoś nieco poważniejszego, będziesz musiał zapoznać się z jednostkami wartości podanymi w różnych wydarzeniach i traktować je z szacunkiem :)

Jørn Schou-Rode
źródło
9
czasami odpowiedź po prostu ją docenia!
Scott Evernden,
1
Na wypadek gdyby ktoś się zastanawiał - ondevicemotion działa w przeglądarce Firefox 8.0, ale jest nieprawidłowo skalowany (0-9), ale wydaje się, że zostało to naprawione w późniejszych wersjach (10.0). Żaden z nich nie działa w przeglądarce Opera Mobile, a wszystkie standardowe działają dobrze na domyślnej przeglądarce Nokia N9.
Nux,
2
Zdarzenie MozOrientation zostało usunięte jako przestarzałe w Firefoksie 6. Więc teraz wszyscy używają standardowego API.
Chris Morgan
Wydaje się, że to nie działa w przeglądarce Firefox 30, jak pokazano na tych skrzypcach . :(
bwinton
sidenote: Plax.js , który jest używany na 404 i 500 stronach github, używa ondeviceorientation .
Yosh,
21

Nie mogę dodać komentarza do doskonałego wyjaśnienia w innym poście, ale chciałem wspomnieć, że świetne źródło dokumentacji można znaleźć tutaj .

Wystarczy zarejestrować funkcję zdarzenia dla akcelerometru:

if(window.DeviceMotionEvent){
  window.addEventListener("devicemotion", motion, false);
}else{
  console.log("DeviceMotionEvent is not supported");
}

z przewodnikiem:

function motion(event){
  console.log("Accelerometer: "
    + event.accelerationIncludingGravity.x + ", "
    + event.accelerationIncludingGravity.y + ", "
    + event.accelerationIncludingGravity.z
  );
}

W przypadku magnetometru należy zarejestrować następujący program obsługi zdarzeń:

if(window.DeviceOrientationEvent){
  window.addEventListener("deviceorientation", orientation, false);
}else{
  console.log("DeviceOrientationEvent is not supported");
}

z przewodnikiem:

function orientation(event){
  console.log("Magnetometer: "
    + event.alpha + ", "
    + event.beta + ", "
    + event.gamma
  );
}

Istnieją również pola określone w zdarzeniu ruchu dla żyroskopu, ale wydaje się, że nie jest to uniwersalnie obsługiwane (np. Nie działało na Samsung Galaxy Note).

Na GitHubie jest prosty działający kod

Nieskończony staż
źródło
1

Przydatne rozwiązanie awaryjne tutaj: 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
źródło