¿Cómo acceder a los datos del acelerómetro / giroscopio de Javascript?
-
09-10-2019 - |
Pregunta
Hace poco me he encontrado unos pocos sitios web que parece tener acceso al acelerómetro o el giroscopio en mi portátil, la detección de cambios en la orientación o movimiento.
¿Cómo se hace esto? ¿Debo suscribirse a algún tipo de evento en el objeto window
?
¿En qué dispositivos (ordenadores portátiles, teléfonos móviles, tabletas) es conocido por este trabajo?
Nota: : En realidad ya lo sé (parte de) la respuesta a esta pregunta, y voy a publicar de inmediato. La razón por la que estoy publicando la cuestión aquí, es dejar que todo el mundo sabe que los datos del acelerómetro es disponible en Javascript (en algunos dispositivos) y el de impugnar la comunidad para publicar nuevos hallazgos sobre el tema. Actualmente, parece que hay casi ninguna documentación de estas características.
Solución
Actualmente hay tres eventos distintos que pueden o no estar activa cuando los dispositivos cliente se mueve. Dos de ellos se centran en torno a Orientación y la última el movimiento
-
ondeviceorientation
se sabe que funciona en la versión de escritorio de Chrome, y la mayoría de los portátiles de Apple parece tener el hardware necesario para que esto funcione. También funciona en Safari Mobile en el iPhone 4 con iOS 4.2. En la función de controlador de eventos, puede acceder aalpha
,beta
, los valoresgamma
en los datos suministrados eventos como el único argumento de la función. -
onmozorientation
se apoya en Firefox 3.6 y posteriores. Una vez más, esto se sabe que el trabajo en la mayoría de los portátiles de Apple, pero podría funcionar en máquinas Windows o Linux con acelerómetro también. En la función de controlador de eventos, busquex
,y
, camposz
en los datos del evento suministrados como primer argumento. -
ondevicemotion
se sabe que funciona en el iPhone 3GS + 4 y IPAD (ambos con iOS 4.2), y proporciona datos relacionados con la aceleración actual del dispositivo de cliente. Los datos de eventos pasados ??a la función de controlador tieneacceleration
yaccelerationIncludingGravity
, que ambos tienen tres campos para cada eje:x
,y
,z
El "terremoto detectar" sitio web de ejemplo utiliza una serie de declaraciones if
Para averiguar qué evento para adjuntar a (en un orden priorizado algo) y pasa los datos recibidos a una función tilt
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 "align" las lecturas de los dos últimos eventos con los de la primera, pero estos son de ninguna manera representaciones precisas. Por este simple "juguete" proyectar funciona muy bien, pero si es necesario utilizar los datos para algo un poco más serio, tendrá que familiarizarse con las unidades de los valores previstos en los diferentes eventos y tratarlos con respeto :)
Otros consejos
Can't add a comment to the excellent explanation in the other post but wanted to mention that a great documentation source can be found here.
It is enough to register an event function for accelerometer like so:
if(window.DeviceMotionEvent){
window.addEventListener("devicemotion", motion, false);
}else{
console.log("DeviceMotionEvent is not supported");
}
with the handler:
function motion(event){
console.log("Accelerometer: "
+ event.accelerationIncludingGravity.x + ", "
+ event.accelerationIncludingGravity.y + ", "
+ event.accelerationIncludingGravity.z
);
}
And for magnetometer a following event handler has to be registered:
if(window.DeviceOrientationEvent){
window.addEventListener("deviceorientation", orientation, false);
}else{
console.log("DeviceOrientationEvent is not supported");
}
with a handler:
function orientation(event){
console.log("Magnetometer: "
+ event.alpha + ", "
+ event.beta + ", "
+ event.gamma
);
}
There are also fields specified in the motion event for a gyroscope but that does not seem to be universally supported (e.g. it didn't work on a Samsung Galaxy Note).
There is a simple working code on GitHub
The way to do this in 2019+ is to use DeviceOrientation
API. This works in most modern browsers on desktop and mobile.
window.addEventListener("deviceorientation", handleOrientation, true);
After registering your event listener (in this case, a JavaScript function called handleOrientation()), your listener function periodically gets called with updated orientation data.
The orientation event contains four values:
DeviceOrientationEvent.absolute
DeviceOrientationEvent.alpha
DeviceOrientationEvent.beta
DeviceOrientationEvent.gamma
The event handler function can look something like this:
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 }
Usefull fallback here: 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);