Detecting device orientation

Esta es una tecnología experimental
Comprueba la Tabla de compabilidad de navegadores cuidadosamente antes de usarla en producción.

Resumen

Cada vez más, los dispositivos habilitados para la web son capaces de determinar su orientación; esto hace que estos puedan reportar datos indicando los cambios de su orientación con relación a la fuerza de gravedad. In particular, dispositivos de mano como los teléfonos móviles pueden usar esta información para rotar la pantalla automaticamente para mostrar información en de forma vertical, presentando un vista extendida del contenido de la web cuando el dispositivo de forma que el ancho es mayor que el alto. 

Hay dos eventos JavaScript que manejan la información de orientación. El primero es DeviceOrientationEvent, que es enviado cuando el aceleromentro detecta un cambio de orientación del dispositivo. Recibiendo y procesando los datos reportados por el evento es posible responder interactivamente a la rotación y aplicar cambios correspondientes al movimiento del dispositivo.

El segundo evento es DeviceMotionEvent, que es enviado cuando un cambio de la aceleración fue añadido. Esto es diferente de DeviceOrientationEvent por que está escuchando cambios de aceleración mas no de orientación. Los sensores son comunmente capaces de detetar DeviceMotionEvent incluso aquellos sensores de laptops que protegen del movimiento a los disposivitos de almacenamiento. DeviceOrientationEvent es comunmente encontrado en dispositivos móviles.

Trabajando con eventos de orientación

Todo lo que necesitas hacer para empezar a recivir cambios de orientación es escuchar el evento deviceorientation:

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

Luego de registrar el evento de escucha (en este caso, una función de JavaScript llamada handleOrientation()), tu función de escucha periodicamente será invocada con una actualización de datos.

La información del evento contiene 4 valores:

El manejador del evento puede lucir como lo siguiente:

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
}

Explicación de los Valores de Orientación

El valor reportado para cada eje indica la cantidad de rotación al rededor de un eje dado, con referencia a un estandar marco de coordenadas. El siguiente enlace describre con mayor detalle la Orientacíon y datos del movimiento explicado que es resumido abajo. 

  • DeviceOrientationEvent.alpha representa el movimiento al rededor del eje z, representado en grados con valores que van desde 0 a 360.
  • DeviceOrientationEvent.beta representa el movimiento del dispositivo al rededor del eje x, representado en grados con valores que van desde -180 a 180.  Esto representa un movimiento de frente hacia atrás del dispositivo.
  • DeviceOrientationEvent.gamma representa el movimiento del dispositivo alrededor del eje y, representado en grados con valores que van de -90 a 90. Esto representa un movimiento de izquiera a derecha del dispositivo.

Ejemplo de orientación

Este ejemplo va a funcionar en cualquier nevegador que soporte el evento deviceorientation y funcione en un dispositivo con capacidades de detectar la orientación.

Entonces imaginemos una pelota en un jardin:

<div class="garden">
  <div class="ball"></div>
</div>

<pre class="output"></pre>

Este jardin tiene 200 pixeles de ancho (Si, es uno pequeño), y la pelota esta en el centro:

.garden {
  position: relative;
  width : 200px;
  height: 200px;
  border: 5px solid #CCC;
  border-radius: 10px;
}

.ball {
  position: absolute;
  top   : 90px;
  left  : 90px;
  width : 20px;
  height: 20px;
  background: green;
  border-radius: 100%;
}

Ahora, si nosotros movemos nuestro dispositivo, la pelota va a moverse acorde a este:

var ball   = document.querySelector('.ball');
var garden = document.querySelector('.garden');
var output = document.querySelector('.output');

var maxX = garden.clientWidth  - ball.clientWidth;
var maxY = garden.clientHeight - ball.clientHeight;

function handleOrientation(event) {
  var x = event.beta;  // In degree in the range [-180,180]
  var y = event.gamma; // In degree in the range [-90,90]

  output.innerHTML  = "beta : " + x + "\n";
  output.innerHTML += "gamma: " + y + "\n";

  // Because we don't want to have the device upside down
  // We constrain the x value to the range [-90,90]
  if (x >  90) { x =  90};
  if (x < -90) { x = -90};

  // To make computation easier we shift the range of 
  // x and y to [0,180]
  x += 90;
  y += 90;

  // 10 is half the size of the ball
  // It center the positioning point to the center of the ball
  ball.style.top  = (maxX*x/180 - 10) + "px";
  ball.style.left = (maxY*y/180 - 10) + "px";
}

window.addEventListener('deviceorientation', handleOrientation);

Aqui el resultado en vivo:

Tener en cuenta: Chrome y Firefox no manejan los angulos de la misma forma, asi que en algunos ejes la dirección se invierte.

Procesando eventos de movimiento

Eventos de movimiento son manejados de la misma manera que la orientación, excepto que estos tienen sus propios nombres de evento: devicemotion

window.addEventListener("devicemotion", handleMotion, true);

Lo que realmente ha cambiado es la información proveida en DeviceMotionEvent objeto pasado como parametro de la función HandleMotion.

El evento de movimiento tiene cuatro propiedades:

Valores de movimiento explicados

DeviceMotionEvent proporciona a los desarrolladores web información sobre la velocidad de los cambios de la posición y orientación del dispositivo. Los cambios son proveidos por sus tres ejes (ver Datos de orientación y movimiento explicados por más detalles).

For acceleration and accelerationIncludingGravity, those axes correspond to the following:

  • x: Representa el eje de oeste a este.
  • y: Representa el eje de sur a norte.
  • z: Representa el eje perpendicular al suelo.

For rotationRate, the situation is a bit different; the information corresponds to the following in each case:

  • alpha: Represents a rotation rate along the axis perpendicular to the screen (or keyboard for desktop).
  • beta: Represents a rotation rate along the axis going from left to right of the plane of the screen (or keyboard for desktop).
  • gamma: Represents a rotation rate along the axis going from bottom to top of the plane of the screen (or keyboard for desktop).

Finally, interval represents the interval of time, in milliseconds, at which data are obtain from the device.

Specifications

Specification Status Comment
DeviceOrientation Event Specification Editor's Draft Initial specification.

Browser compatibility

We're converting our compatibility data into a machine-readable JSON format. This compatibility table still uses the old format, because we haven't yet converted the data it contains. Find out how you can help!
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
DeviceOrientationEvent 7.0 3.6[1]
6
? ? ?
DeviceMotionEvent (Yes) 6 ? ? ?
Feature Android Firefox Mobile (Gecko) IE Phone Opera Mobile Safari Mobile
DeviceOrientationEvent 3.0 3.6[1]
6
Sin soporte Sin soporte 4.2
DeviceMotionEvent (Yes) 6 ? ? ?

Note: gyronorm.js is a polyfill for normalizing the accelerometer and gyroscope data on mobile devices. This is useful for overcoming some of the differences in device support for device orientation.

Gecko implementation notes

  1. Firefox 3.6, 4, and 5 supported mozOrientation versus the standard DeviceOrientationEvent event

See also