¿Cómo acceder a los datos del acelerómetro / giroscopio desde Javascript?

139

Recientemente me he encontrado con algunos sitios web que parecen acceder al acelerómetro o giroscopio en mi computadora portátil, detectando cambios en la orientación o el movimiento.

¿Cómo se hace esto? ¿Debo suscribirme a algún tipo de evento en el windowobjeto?

¿En qué dispositivos (computadoras portátiles, teléfonos móviles, tabletas) se sabe que esto funciona?


NB : De hecho, ya sé (parte de) la respuesta a esta pregunta, y la voy a publicar de inmediato. La razón por la que estoy publicando la pregunta aquí, es para que todos los demás sepan que los datos del acelerómetro están disponibles en Javascript (en ciertos dispositivos) y para desafiar a la comunidad a publicar nuevos hallazgos sobre el tema. Actualmente, parece que casi no hay documentación de estas características.

Jørn Schou-Rode
fuente
Gran esfuerzo, muchas gracias. ¿Crees que 3 años después la respuesta necesita alguna actualización?
Bartek Banachewicz
@BartekBanachewicz Gracias por llamarme en este caso. Transferiré la respuesta a "wiki de la comunidad", con la esperanza de que alguien con conocimientos más actualizados la actualice para reflejar el estado actual de la técnica.
Jørn Schou-Rode
No pude encontrar si esta operación requiere el consentimiento del usuario. No quería hacer una nueva pregunta ya que encaja perfectamente con su pregunta. ¿Quizás podamos agregar esto aquí? ¿Alguien sabe si esto requiere un consentimiento explícito? ¿Es este el caso en todos los navegadores y todos los sistemas operativos móviles?
Plata

Respuestas:

8

La forma de hacer esto en 2019+ es usar DeviceOrientationAPI . Esto funciona en la mayoría de los navegadores modernos en computadoras de escritorio y dispositivos móviles.

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

Después de registrar su escucha de eventos (en este caso, una función de JavaScript llamada handleOrientation ()), su función de escucha se llama periódicamente con datos de orientación actualizados.

El evento de orientación contiene cuatro valores:

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

La función del controlador de eventos puede verse así:

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
fuente
179

Actualmente hay tres eventos distintos que pueden o no activarse cuando se mueven los dispositivos del cliente. Dos de ellos se centran en la orientación y el último en el movimiento :

  • ondeviceorientationse sabe que funciona en la versión de escritorio de Chrome, y la mayoría de las computadoras portátiles de Apple parecen tener el hardware necesario para que esto funcione. También funciona en Mobile Safari en el iPhone 4 con iOS 4.2. En la función de controlador de eventos, puede acceder alpha, beta, gammalos valores de los datos del evento suministrados como el único argumento de la función.

  • onmozorientationes compatible con Firefox 3.6 y versiones posteriores. Nuevamente, se sabe que esto funciona en la mayoría de las computadoras portátiles de Apple, pero también podría funcionar en máquinas Windows o Linux con acelerómetro. En la función de controlador de eventos, busque x, y, zcampos en los datos del evento suministran como primer argumento.

  • ondevicemotionse sabe que funciona en iPhone 3GS + 4 y iPad (ambos con iOS 4.2), y proporciona datos relacionados con la aceleración actual del dispositivo cliente. Los datos de eventos pasados a la función de controlador tiene accelerationy accelerationIncludingGravityque ambos tienen tres campos para cada eje: x, y,z

El sitio web de muestra "detección de terremotos" utiliza una serie de ifdeclaraciones para determinar a qué evento adjuntar (en un orden algo prioritario) y pasa los datos recibidos a una tiltfunción común :

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

Los factores constantes 2 y 50 se utilizan para "alinear" las lecturas de los dos últimos eventos con las del primero, pero de ninguna manera son representaciones precisas. Para este simple proyecto de "juguete" funciona bien, pero si necesita utilizar los datos para algo un poco más serio, deberá familiarizarse con las unidades de los valores proporcionados en los diferentes eventos y tratarlos con respeto :)

Jørn Schou-Rode
fuente
9
a veces una respuesta solo lo clava!
Scott Evernden
1
En caso de que alguien se pregunte, ondevicemotion funciona para Firefox 8.0 pero está escalado incorrectamente (0-9), pero esto parece solucionarse en versiones posteriores (10.0). Ninguno de ellos funciona en Opera Mobile y todos los estándares funcionan bien en el navegador predeterminado Nokia N9.
Nux
2
El evento MozOrientation se eliminó como obsoleto en Firefox 6. Así que ahora todos usan la API estandarizada.
Chris Morgan
Esto no parece funcionar en Firefox 30, como se muestra en este violín . :(
bwinton
nota al margen: Plax.js , que se usa en las páginas 404 y 500 de github , usa ondeviceorientation .
Yosh
21

No se puede agregar un comentario a la excelente explicación en la otra publicación, pero quería mencionar que se puede encontrar una excelente fuente de documentación aquí .

Es suficiente registrar una función de evento para acelerómetro así:

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

con el manejador:

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

Y para el magnetómetro se debe registrar un siguiente controlador de eventos:

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

con un controlador:

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

También hay campos especificados en el evento de movimiento para un giroscopio, pero eso no parece ser universalmente compatible (por ejemplo, no funcionó en un Samsung Galaxy Note).

Hay un código de trabajo simple en GitHub

Prácticas infinitas
fuente
1

Respaldo útil aquí: 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
fuente