Hvordan få tilgang til akselerometer-/gyroskopdata fra Javascript?


Jeg har nylig kommet over noen nettsteder som ser ut til å få tilgang til akselerometeret eller gyroskopet på laptopen min, og oppdager endringer i orientering eller bevegelse.

Hvordan gjøres dette? Må jeg abonnere på en slags hendelse på window-objektet?

På hvilke enheter (bærbare datamaskiner, mobiltelefoner, nettbrett) er det kjent at dette fungerer?

NB: Jeg vet faktisk allerede (en del av) svaret på dette spørsmålet, og jeg kommer til å poste det med en gang. Grunnen til at jeg legger ut spørsmålet her, er for å la alle andre vite at akselerometerdata er tilgjengelig i Javascript (på visse enheter) og for å utfordre fellesskapet til å poste nye funn om emnet. Per nå ser det ut til å være nesten ingen dokumentasjon om disse funksjonene.

Svar #1

Det er for tiden tre forskjellige hendelser som kan eller ikke kan utløses når klientenheten beveger seg. To av dem er fokusert rundt orientering og den siste på bevegelse:

  • ondeviceorientation er kjent for å fungere på skrivebordsversjonen av Chrome, og de fleste Apple-bærbare ser ut til å ha maskinvaren som kreves for at dette skal fungere. Det fungerer også på Mobile Safari på iPhone 4 med iOS 4.2. I hendelseshåndteringsfunksjonen kan du få tilgang til alpha, beta, gamma-verdiene i hendelsesdataene som leveres som det eneste argumentet til funksjonen.

  • onmozorientation støttes i Firefox 3.6 og nyere. Igjen, dette er kjent for å fungere på de fleste Apple-bærbare datamaskiner, men kan også fungere på Windows- eller Linux-maskiner med akselerometer. I hendelsesbehandlerfunksjonen, se etter x, y, z-feltene i hendelsesdataene som leveres som første argument.

  • ondevicemotion er kjent for å fungere på iPhone 3GS + 4 og iPad (begge med iOS 4.2), og gir data relatert til den nåværende akselerasjonen til klientenheten. Hendelsesdataene som sendes til håndteringsfunksjonen har acceleration og accelerationIncludingGravity, som begge har tre felt for hver akse: x, y, z

Det "jordskjelv-detekterende" eksempelnettsiden bruker en serie med if-setninger for å finne ut hvilket hendelse som skal knyttes til (i en noe prioritert rekkefølge) og sender de mottatte dataene til en felles tilt-funksjon:

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

De konstante faktorene 2 og 50 brukes for å «justere» avlesningene fra de to siste hendelsene med de fra den første, men disse er på ingen måte nøyaktige representasjoner. For dette enkle «leke»-prosjektet fungerer det helt fint, men hvis du trenger å bruke dataene til noe litt mer seriøst, må du bli kjent med enhetene til verdiene som er gitt i de forskjellige hendelsene og behandle dem deretter :)

Svar #2

Kan ikke legge til en kommentar til den utmerkede forklaringen i det andre innlegget, men ville nevne at en god dokumentasjonskilde kan finnes her.

Det er nok å registrere en hendelsesfunksjon for akselerometeret slik:

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

med handleren:

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

Og for magnetometer må en følgende hendelseshåndterer registreres:

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

med en håndterer:

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

Det finnes også felt spesifisert i bevegelsesbegivenheten for et gyroskop, men det ser ikke ut til å være allment støttet (f.eks. fungerte det ikke på en Samsung Galaxy Note).

Det finnes en enkel fungerende kode på GitHub

Svar #3

Måten å gjøre dette på i 2019+ er å bruke DeviceOrientation-API. Dette fungerer i de fleste moderne nettlesere på stasjonære og mobile enheter.

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

Etter at du har registrert din hendelseslytter (i dette tilfellet en JavaScript-funksjon kalt handleOrientation()), blir lytterfunksjonen din periodisk kalt med oppdatert orienteringsdata.

Orienteringsarrangementet inneholder fire verdier:

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

Hendelseshåndteringsfunksjonen kan se omtrent slik ut:

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
}

Relaterte artikler