Niveau : Confirmé

Device Orientation et Device Motion API

Tutoriel par (Lycéen, Obersoultzbach)
Créé le (20352 lectures)
Tags : javascript, html5, orientation, mobile, motion, acceleration

Le web d’aujourd’hui est en train d’être conquis par nos amis les appareils mobiles et plus précisément les smartphones et les tablettes. Or ces terminaux possèdent quelque chose que très peu de nos chers ordinateurs fixes ont : un accéléromètre. Ce petit composant permet de connaître l’inclinaison presque exacte de l’appareil dans l’espace, c’est à dire sur trois axes x, y et z et l'accélération subite par l'appareil sur ces mêmes axes.

Avec l’arrivée de HTML5, une flopée de nouvelle API JavaScript ont fait leur apparition, dont la Device Orientation API et la Device Motion API.

Device Orientation API

C’est avec cette API que l’on va pouvoir collecter les données d'inclinaison envoyées par l’accéléromètre pour ensuite les utiliser dans diverses applications. Lançons nous sans plus attendre dans le code !

Tout d’abord, nous allons faire une page toute simple avec juste un élément div :

<!DOCTYPE html>
<html>
  <head>
   <meta charset = "utf-8" />
   <title>Device Orientation API</title>
  </head>
  <body>
   <div id="log"></div>
  </body>
</html>

Passons maintenant au code JavaScript. Une fonction sera lancée lorsque l’événement deviceorientation sera déclenché, appelant une fonction de callback nommée process. La méthode addEventListener permet d'attacher cette fonction appelée en retour, à l'événement deviceorientation. Attention, elle n'est pas disponible sur les anciens moteurs d'Internet Explorer jusqu'à la version 8 incluse (il faudra dans ce cas se pencher vers attachEvent ou passer par un framework JavaScript simplifiant les appels).

if(window.DeviceOrientationEvent) {
  window.addEventListener("deviceorientation", process, false);
} else {
  // Le navigateur ne supporte pas l'événement deviceorientation
}

Cette fonction va récupérer les valeur alpha, beta et gamma et va les afficher dans l'élément div pour avoir un retour sur le document. Ces valeurs sont stockées dans l'objet event récupéré par la fonction de callback.

function process(event) {
  var alpha = event.alpha;
  var beta = event.beta;
  var gamma = event.gamma;
  document.getElementById("log").innerHTML = "<ul><li>Alpha : " + alpha + "</li><li>Beta : " + beta + "</li><li>Gamma : " + gamma + "</li></ul>"; 
}

Mais attendez ! Je ne vous ai même pas défini alpha beta et gamma :

  • alpha représente l’angle de rotation (en degrés) autour de l’axe Z
  • beta représente l’angle d’inclinaison (en degrés) autour de l’axe X
  • gamma représente l’angle d’inclinaison (en degrés) autour de l’axe Y

Toutes ces valeurs sont théoriquement à 0 lorsque l’appareil est posé à plat et qu'il n'a pas bougé depuis le chargement de la page. Par contre, tout dépend du matériel : un détecteur un peu sensible pourra constamment signaler des valeurs changeantes alors même que le mobile est immobile. Il faudra alors prendre le relais sur les valeurs renvoyées pour ignorer les plus infimes variations ou les arrondir.

Notre script est complet en fonctionnel. Le voilà en action :

Démonstration en ligne

Vous remarquerez qu’il y a beaucoup de chiffres après la virgule. Dans certains cas, il est préférable d’arrondir ces valeurs à l’aide de Math.round(), comme par exemple lorsqu’on veut faire bouger un bloc en fonction de l’orientation de l’appareil. Dans ce cas, si les valeurs ne sont pas arrondies, on peut observer un tremblement du bloc en question dû aux valeurs de alpha, beta et gamma qui changent constamment.

Device Motion API

L'API Device Motion ne retourne pas de valeurs d'angles mais d'accélération en mètres par seconde au carré (m/s²), sur les trois axes x, y et z. Son usage est semblable celui de l'Orientation.

Appelons à nouveau notre fonction callback mais cette fois lorsque l'évènement devicemotion est déclenché.

if(window.DeviceMotionEvent) {
  window.addEventListener("devicemotion", process, false);
} else {
  // Le navigateur ne supporte pas l'événement devicemotion
}

Déclarons ensuite notre fonction callback qui affichera les valeurs d'accélération dans notre div.

function process(event) {
  var x = event.accelerationIncludingGravity.x;
  var y = event.accelerationIncludingGravity.y;
  var z = event.accelerationIncludingGravity.z;
  document.getElementById("log").innerHTML = "<ul><li>X : " + x + "</li><li>Y : " + y + "</li><li>Z : " + z + "</li></ul>"; 
}

L'objet event retourne deux propriétés :

  • acceleration : L'accélération calculée par l'appareil en enlevant la gravité.
  • accelerationIncludingGravity : La valeur de l'accélération brute, retournée par l'accéléromètre.

Ainsi, lorsque l'appareil est posé à plat et ne bouge pas, on obtiendra théoriquement :

  • Avec acceleration : {0,0,0}
  • Avec accelerationIncludingGravity : {0,0,9.81}

Ici 9.81 correspond à la valeur de la pesanteur en gravité terrestre. Il est recommandé d'utiliser accelerationIncludingGravity car certains appareils ne peuvent pas calculer une accélération en y soustrayant la gravité, et on obtiendrait alors avec acceleration les mêmes valeurs qu'avec accelerationIncludingGravity.

Démonstration en ligne

Encore une fois, vous remarquerez que les valeurs changent tout le temps, même lorsque l'appareil est immobile, ceci à cause de la précision variable de l'accéléromètre.

Conclusion

Voilà donc deux API très utiles pour développer des jeux pour mobiles (avec canvas notamment), ou créer une interaction supplémentaire avec le document, par exemple un effet parallaxe en fonction de l'inclinaison de l'appareil.

Ressources utiles

Commentaires

Ekios a dit le

Petite info pour les utilisateurs d'anciens mobiles android : en 2.3.x vous pouvez installer le navigateur Opéra pour apprécier la démo de cette API :)

Le navigateur d'origine, Dolphin, Skyfire et Ninesky ne gérant pas l'event "deviceorientation".(Oui, je les ai tous installé ...)

PS : HTC Desire, Cyano 7.2

Gili a dit le

Merci c'est très intéressent.

KevinPy a dit le

Merci pour cette article intéréssant. Cela m'a d'ailleurs donné l'idée de créer une webapp pour se servir du device come un niveau.

Voici le lien: http://codrrr.com/labo/webapps/0level