Come accedere ai dati dell'accelerometro / giroscopio da Javascript?


139

Di recente mi sono imbattuto in alcuni siti Web che sembrano accedere all'accelerometro o al giroscopio sul mio laptop, rilevando cambiamenti nell'orientamento o nel movimento.

Come si fa? Devo abbonarmi a qualche tipo di evento windowsull'oggetto?

Su quali dispositivi (laptop, telefoni cellulari, tablet) funziona?


NB : In realtà conosco già (parte di) la risposta a questa domanda e la pubblicherò subito. Il motivo per cui sto pubblicando la domanda qui è di far sapere a tutti che i dati dell'accelerometro sono disponibili in Javascript (su alcuni dispositivi) e di sfidare la comunità a pubblicare nuovi risultati sull'argomento. Attualmente, sembra che non ci sia quasi nessuna documentazione di queste funzionalità.


Grande sforzo, grazie mille. Pensi che 3 anni dopo la risposta abbia bisogno di aggiornamenti?
Bartek Banachewicz,

@BartekBanachewicz Grazie per avermi chiamato per questo. Trasferirò la risposta a "community wiki", sperando che qualcuno con una conoscenza più aggiornata la aggiorni per riflettere lo stato dell'arte attuale.
Jørn Schou-Rode,

Non sono riuscito a trovare se questa operazione richiede il consenso dell'utente. Non volevo fare una nuova domanda poiché si adatta perfettamente alla tua domanda. Forse possiamo aggiungere questo qui? Qualcuno sa se questo richiede un consenso esplicito? È questo il caso in tutti i browser e tutti i sistemi operativi mobili?
Argento

Risposte:


8

Il modo per farlo nel 2019+ è utilizzare l' DeviceOrientationAPI . Funziona con la maggior parte dei browser moderni su desktop e dispositivi mobili.

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

Dopo aver registrato il listener di eventi (in questo caso, una funzione JavaScript denominata handleOrientation ()), la funzione listener viene periodicamente chiamata con i dati di orientamento aggiornati.

L'evento di orientamento contiene quattro valori:

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

La funzione del gestore eventi può essere simile a questa:

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
}

179

Esistono attualmente tre eventi distinti che possono essere attivati ​​o meno quando i dispositivi client si spostano. Due di questi sono focalizzati sull'orientamento e l'ultimo sul movimento :

  • ondeviceorientationè noto per funzionare sulla versione desktop di Chrome e la maggior parte dei laptop Apple sembra avere l'hardware necessario per farlo funzionare. Funziona anche su Mobile Safari su iPhone 4 con iOS 4.2. Nella funzione gestore di eventi, è possibile accedere alpha, beta, gammai valori sui dati degli eventi forniti come unico argomento della funzione.

  • onmozorientationè supportato su Firefox 3.6 e versioni successive. Ancora una volta, questo è noto per funzionare sulla maggior parte dei laptop Apple, ma potrebbe funzionare anche su macchine Windows o Linux con accelerometro. Nella funzione gestore di eventi, cercare x, y, zcampi i dati degli eventi forniti come primo argomento.

  • ondevicemotionè noto per funzionare su iPhone 3GS + 4 e iPad (entrambi con iOS 4.2) e fornisce dati relativi all'accelerazione corrente del dispositivo client. I dati degli eventi passati alla funzione di gestione ha acceleratione accelerationIncludingGravityche entrambi hanno tre campi per ogni asse: x, y,z

Il sito Web di esempio "rilevamento terremoti" utilizza una serie di ifdichiarazioni per capire a quale evento collegarsi (in un ordine un po 'prioritario) e passa i dati ricevuti a una tiltfunzione comune :

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

I fattori costanti 2 e 50 sono usati per "allineare" le letture di questi ultimi due eventi con quelle del primo, ma queste non sono affatto rappresentazioni precise. Per questo semplice progetto "giocattolo" funziona benissimo, ma se devi usare i dati per qualcosa di leggermente più serio, dovrai familiarizzare con le unità dei valori forniti nei diversi eventi e trattarli con rispetto :)


9
a volte una risposta lo inchioda!
Scott Evernden,

1
Nel caso qualcuno si chieda: ondevicemotion funziona per Firefox 8.0 ma è ridimensionato in modo errato (0-9), ma questo sembra essere stato risolto nelle versioni successive (10.0). Nessuno di loro funziona su Opera Mobile e tutti quelli standard funzionano bene sul browser Nokia N9 predefinito.
Nux,

2
L'evento MozOrientation è stato rimosso come obsoleto in Firefox 6. Quindi ora utilizzano tutti l'API standardizzata.
Chris Morgan,

Questo non sembra funzionare in Firefox 30, come mostrato in questo violino . :(
bwinton,

sidenote: Plax.js , che viene utilizzato nelle pagine 404 e 500 di github, utilizza ondeviceorientation .
Yosh,

21

Non posso aggiungere un commento all'eccellente spiegazione nell'altro post, ma volevo menzionare che una grande fonte di documentazione può essere trovata qui .

È sufficiente registrare una funzione evento per l'accelerometro in questo modo:

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

con il gestore:

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

E per il magnetometro deve essere registrato un seguente gestore di eventi:

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

con un gestore:

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

Ci sono anche campi specificati nell'evento di movimento per un giroscopio ma che non sembrano essere universalmente supportati (ad esempio, non ha funzionato su un Samsung Galaxy Note).

C'è un semplice codice funzionante su GitHub


1

Fallback utile qui: 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);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.