web-dev-qa-db-fra.com

Comment accéder aux données d'accéléromètre / gyroscope à partir de Javascript?

Je suis récemment tombé sur quelques sites Web qui semblent accéder à l'accéléromètre ou au gyroscope de mon ordinateur portable, détectant les changements d'orientation ou de mouvement.

Comment est-ce fait? Dois-je m'abonner à une sorte d'événement sur l'objet window?

Sur quels appareils (ordinateurs portables, téléphones mobiles, tablettes) cela fonctionne-t-il?


NB : En fait, je connais déjà (une partie de) la réponse à cette question et je vais la poster tout de suite. La raison pour laquelle je pose la question ici est pour que tout le monde sache que les données de l'accéléromètre sont disponibles en Javascript (sur certains appareils) et pour contester la communauté à publier de nouvelles découvertes sur le sujet. Actuellement, il semble n'y avoir presque aucune documentation de ces fonctionnalités.

131
Jørn Schou-Rode

Il existe actuellement trois événements distincts qui peuvent ou non être déclenchés lorsque les périphériques clients sont déplacés. Deux d'entre eux sont centrés sur l'orientation et le dernier sur le mouvement :

  • ondeviceorientation est connu pour fonctionner sur la version de bureau de Chrome, et la plupart des ordinateurs portables Apple) semblent disposer du matériel nécessaire pour que cela fonctionne. Il fonctionne également sur Mobile Safari sur iPhone 4 avec iOS 4.2 Dans la fonction de gestionnaire d'événements, vous pouvez accéder aux valeurs alpha, beta, gamma des données d'événement fournies comme seul argument de la fonction.

  • onmozorientation est supporté par Firefox 3.6 et plus récent. Encore une fois, on sait que cela fonctionne sur la plupart des ordinateurs portables Apple, mais peut également fonctionner sur des machines Windows ou Linux avec accéléromètre. Dans la fonction de gestion des événements, recherchez x, y, z champs sur les données d'événement fournies comme premier argument.

  • ondevicemotion est connu pour fonctionner sur l'iPhone 3GS + 4 et l'iPad (tous deux avec iOS 4.2) et fournit des données relatives à l'accélération actuelle du périphérique client. Les données d'événement transmises à la fonction de gestionnaire ont acceleration et accelerationIncludingGravity, qui ont chacune trois champs pour chaque axe: x, y, z

L'exemple de site Web "Détection de tremblement de terre" utilise une série d'instructions if pour déterminer à quel événement se connecter (dans un ordre relativement prioritaire) et transmet les données reçues à une fonction tilt commune:

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

Les facteurs constants 2 et 50 sont utilisés pour "aligner" les lectures des deux derniers événements sur celles du premier, mais elles sont nullement précises représentations. Pour ce simple projet "jouet", cela fonctionne très bien, mais si vous devez utiliser les données pour quelque chose de légèrement plus sérieux, vous devrez vous familiariser avec les unités des valeurs fournies dans les différents événements et les traiter avec respect :)

179
Jørn Schou-Rode

Impossible d'ajouter un commentaire à l'excellente explication de l'autre billet mais je voulais mentionner qu'une source de documentation intéressante peut être trouvée ici .

Il suffit d’enregistrer une fonction d’événement pour accéléromètre comme ceci:

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

avec le gestionnaire:

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

Et pour le magnétomètre, un gestionnaire d'événements suivant doit être enregistré:

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

avec un gestionnaire:

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

Il existe également des champs spécifiés dans l'événement de mouvement pour un gyroscope, mais cela ne semble pas être universellement pris en charge (par exemple, cela ne fonctionnait pas sur un Samsung Galaxy Note).

Il y a un code de travail simple sur GitHub

20

La manière de faire cela en 2019+ est d'utiliser DeviceOrientation API . Cela fonctionne dans la plupart des navigateurs modernes sur les ordinateurs de bureau et mobiles.

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

Après avoir enregistré votre écouteur d'événement (dans ce cas, une fonction JavaScript appelée handleOrientation ()), votre fonction d'écoute est appelée périodiquement avec des données d'orientation mises à jour.

L'événement d'orientation contient quatre valeurs:

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

La fonction de gestionnaire d'événement peut ressembler à ceci:

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
}
3
str

Solution de secours utile ici: 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);
1
Luckylooke