Développement Web multitouch

Boris Smus
Boris Smus

Introduction

Les appareils mobiles tels que les smartphones et les tablettes sont généralement dotés d'un écran tactile capacitif pour capturer les interactions effectuées avec les doigts de l'utilisateur. À mesure que le Web mobile évolue pour permettre des applications de plus en plus sophistiquées, les développeurs Web ont besoin d'un moyen de gérer ces événements. Par exemple, dans presque tous les jeux au rythme rapide, le joueur doit appuyer sur plusieurs boutons à la fois, ce qui, dans le contexte d'un écran tactile, implique l'utilisation de plusieurs boutons.

Apple a lancé son API Touch Events dans iOS 2.0. Android s'est adapté à cette norme de facto et a comblé cette lacune. Un groupe de travail du W3C s'est récemment réuni pour travailler sur cette spécification des événements tactiles.

Dans cet article, nous nous pencherons sur l'API des événements tactiles fournie par les appareils iOS et Android, ainsi que sur le Chrome pour ordinateur de bureau compatible avec l'écran tactile. Nous explorerons également les types d'applications que vous pouvez créer, puis nous vous présenterons quelques bonnes pratiques et des techniques utiles qui facilitent le développement d'applications tactiles.

Événements tactiles

Trois événements tactiles de base sont décrits dans la spécification et implémentés largement sur les appareils mobiles:

  • touchstart: un doigt est placé sur un élément DOM.
  • touchmove: fait glisser un doigt le long d'un élément DOM.
  • touchend: un doigt est retiré d'un élément DOM.

Chaque événement tactile comprend trois listes d'appuis:

  • touches: liste de tous les doigts actuellement affichés à l'écran.
  • targetTouches: liste de doigts sur l'élément DOM actuel.
  • changedTouches: liste des doigts impliqués dans l'événement en cours. Par exemple, dans un événement "touchend", il s'agit du doigt retiré.

Ces listes sont constituées d'objets contenant des informations tactiles:

  • Identifiant: numéro qui identifie de manière unique le doigt actif dans la session tactile.
  • target: élément DOM qui était la cible de l'action.
  • Coordonnées du client/de la page/de l'écran: l'endroit où l'action s'est produite à l'écran.
  • coordonnées de rayon et angle de rotation: décrivez l'ellipse qui ressemble à la forme d'un doigt.

Applications tactiles

Les événements touchstart, touchmove et touchend offrent un ensemble de fonctionnalités suffisamment riche pour permettre pratiquement tout type d'interaction tactile, y compris tous les gestes à plusieurs doigts habituels tels que le pincement, le zoom, la rotation, etc.

Cet extrait vous permet de faire glisser un élément DOM à l'aide d'un seul doigt:

var obj = document.getElementById('id');
obj.addEventListener('touchmove', function(event) {
  // If there's exactly one finger inside this element
  if (event.targetTouches.length == 1) {
    var touch = event.targetTouches[0];
    // Place element where the finger is
    obj.style.left = touch.pageX + 'px';
    obj.style.top = touch.pageY + 'px';
  }
}, false);

Vous trouverez ci-dessous un exemple qui affiche tous les éléments sélectionnés à l'écran. Il est utile juste d’avoir une sentiment de la réactivité de l’appareil.

Suivi des doigts
// Setup canvas and expose context via ctx variable
canvas.addEventListener('touchmove', function(event) {
  for (var i = 0; i < event.touches.length; i++) {
    var touch = event.touches[i];
    ctx.beginPath();
    ctx.arc(touch.pageX, touch.pageY, 20, 0, 2*Math.PI, true);
    ctx.fill();
    ctx.stroke();
  }
}, false);

Démonstrations

Un certain nombre de démos multitouch intéressantes sont déjà à l'honneur, comme cette démonstration de dessin sur toile de Paul Irish, entre autres.

Dessin d&#39;une capture d&#39;écran

Et Browser Ninja, une démo technique qui est un clone de Fruit Ninja utilisant des transformations et des transitions CSS3, ainsi qu'un canevas:

Navigateur ninja

Bonnes pratiques

Empêcher le zoom

Les paramètres par défaut ne fonctionnent pas très bien pour les gestes à plusieurs doigts, car les balayages et les gestes sont souvent associés au comportement du navigateur, comme le défilement et le zoom.

Pour désactiver le zoom, configurez votre fenêtre d'affichage de sorte qu'elle ne soit pas évolutive par l'utilisateur à l'aide de la balise Meta suivante:

<meta name="viewport" 
  content="width=device-width, initial-scale=1.0, user-scalable=no>

Pour en savoir plus sur la configuration de votre fenêtre d'affichage, consultez cet article sur les créations HTML5 pour mobile.

Empêcher le défilement

Certains appareils mobiles ont des comportements par défaut pour le déplacement tactile, comme l'effet de défilement hors limites classique d'iOS, qui provoque un rebond de la vue lorsque le défilement dépasse les limites du contenu. Cette fonctionnalité est source de confusion dans de nombreuses applications multitouch et peut être facilement désactivée:

document.body.addEventListener('touchmove', function(event) {
  event.preventDefault();
}, false); 

Effectuer un rendu attentif

Si vous développez une application multipoint impliquant des gestes complexes à plusieurs doigts, faites attention à la manière dont vous réagissez aux événements tactiles, car vous allez en gérer beaucoup à la fois. Prenons l'exemple de la section précédente, qui dessine tous les points de contact à l'écran. Vous pouvez dessiner dès qu'il y a une entrée tactile:

canvas.addEventListener('touchmove', function(event) {
  renderTouches(event.touches);
}, false);

Toutefois, cette technique n'est pas adaptée au nombre de doigts sur l'écran. À la place, vous pouvez suivre tous les doigts et effectuer un rendu en boucle pour obtenir de bien meilleures performances:

var touches = []
canvas.addEventListener('touchmove', function(event) {
  touches = event.touches;
}, false);

// Setup a 60fps timer
timer = setInterval(function() {
  renderTouches(touches);
}, 15);

Utiliser targetTouches et changedTouches

N'oubliez pas que event.touches est un tableau de TOUS les doigts en contact avec l'écran, pas seulement ceux qui se trouvent sur la cible de l'élément DOM. Il peut être beaucoup plus utile d'utiliser event.targetTouches ou event.changedTouches à la place.

Enfin, étant donné que vous développez des applications pour mobile, vous devez connaître les bonnes pratiques générales sur mobile, qui sont abordées dans l'article d'Eric Bidelman et dans ce document du W3C.

Assistance relative aux appareils

Malheureusement, l'exhaustivité et la qualité des implémentations d'événements tactiles varient considérablement. J'ai écrit un script de diagnostic qui affiche des informations de base sur l'implémentation de l'API tactile, y compris les événements compatibles et la résolution de déclenchement de touchmove. J'ai testé Android 2.3.3 sur le Nexus One et le Nexus S, Android 3.0.1 sur Xoom, et iOS 4.2 sur iPad et iPhone.

En bref, tous les navigateurs testés sont compatibles avec les événements touchstart, touchend et touchmove.

La spécification fournit trois événements tactiles supplémentaires, mais aucun navigateur testé ne les prend en charge:

  • touchenter: un doigt en mouvement entre dans un élément DOM.
  • touchleave: un doigt en mouvement quitte un élément DOM.
  • touchcancel: une opération tactile est interrompue (spécifique à l'implémentation).

Dans chaque liste tactile, les navigateurs testés fournissent également les listes tactiles touches, targetTouches et changedTouches. Toutefois, aucun navigateur testé n'est compatible avec les propriétés RadiusX, RadiusY ou rotationAngle, qui indiquent la forme du doigt touchant l'écran.

Lors d'un mouvement tactile, les événements se déclenchent environ 60 fois par seconde sur tous les appareils testés.

Android 2.3.3 (Nexus)

Le navigateur Android Gingerbread (testé sur Nexus One et Nexus S) n'est pas compatible avec l'utilisation de l'écran tactile multipoint. Il s'agit d'un problème connu.

Android 3.0.1 (Xoom)

Le navigateur de Xoom est compatible avec la fonctionnalité multipoint de base, mais elle ne fonctionne que sur un seul élément DOM. Le navigateur ne répond pas correctement à deux appuis simultanés sur différents éléments DOM. En d'autres termes, l'application suivante réagit à deux pressions simultanées:

obj1.addEventListener('touchmove', function(event) {
  for (var i = 0; i < event.targetTouches; i++) {
    var touch = event.targetTouches[i];
    console.log('touched ' + touch.identifier);
  }
}, false);

Mais ce qui suit ne va pas:

var objs = [obj1, obj2];
for (var i = 0; i < objs.length; i++) {
  var obj = objs[i];
  obj.addEventListener('touchmove', function(event) {
    if (event.targetTouches.length == 1) {
      console.log('touched ' + event.targetTouches[0].identifier);
    }
  }, false);
}

iOS 4.x (iPad, iPhone)

Les appareils iOS sont entièrement compatibles avec le multipoint, sont capables de suivre un grand nombre de doigts et offrent une expérience tactile très réactive dans le navigateur.

Outils pour les développeurs

Dans le développement pour mobile, il est souvent plus facile de commencer le prototypage sur ordinateur de bureau, puis de s'attaquer aux parties spécifiques aux mobiles sur les appareils que vous souhaitez prendre en charge. La fonctionnalité tactile multipoint est l'une des fonctionnalités difficiles à tester sur les PC, car la plupart d'entre eux n'ont pas de saisie tactile.

Effectuer des tests sur mobile peut allonger votre cycle de développement, car chaque modification que vous effectuez doit être transmise à un serveur, puis chargée sur l'appareil. Ensuite, une fois l'application exécutée, vous ne pourrez rien faire pour déboguer votre application, car les tablettes et les smartphones ne disposent pas d'outils pour les développeurs Web.

Une solution à ce problème consiste à simuler des événements tactiles sur votre ordinateur de développement. Pour les gestes à toucher unique, les événements tactiles peuvent être simulés à partir des événements de souris. Les événements tactiles multipoints peuvent être simulés si vous disposez d'un appareil avec saisie tactile, comme un MacBook d'Apple moderne.

Événements tactiles

Si vous souhaitez simuler des événements tactiles sur votre ordinateur, Chrome propose une émulation d'événements tactiles à partir des outils pour les développeurs. Ouvrez les outils de développement, sélectionnez l'icône en forme de roue dentée des paramètres, puis "Remplacements" ou "Émulation" et activez "Émuler les événements tactiles".

Pour les autres navigateurs, vous pouvez essayer Phantom Limmb, qui simule les événements tactiles sur les pages et permet également de démarrer.

Le plug-in jQuery Touchable permet également d'unifier les événements tactiles et de souris sur toutes les plates-formes.

Événements tactiles multipoint

Pour que votre application Web multipoint fonctionne dans votre navigateur sur votre pavé tactile multipoint (Apple MacBook ou MagicPad, par exemple), j'ai créé le polyfill MagicTouch.js. Il capture les événements tactiles de votre pavé tactile et les convertit en événements tactiles standards.

  1. Téléchargez et installez le plug-in NPAPI npTuioClient dans ~/Library/Internet Plug-Ins/.
  2. Téléchargez l'application TUIO de TongSeng pour le MagicPad de Mac, puis démarrez le serveur.
  3. Téléchargez MagicTouch.js, une bibliothèque JavaScript permettant de simuler des événements tactiles compatibles avec les spécifications en fonction des rappels npTuioClient.
  4. Incluez le script magic.js et le plug-in npTuioClient dans votre application comme suit:
<head>
  ...
  <script src="/path/to/magictouch.js"></script>
</head>

<body>
  ...
  <object id="tuio" type="application/x-tuio" style="width: 0px; height: 0px;">
    Touch input plugin failed to load!
  </object>
</body>

Vous devrez peut-être activer le plug-in.

Une démonstration en direct avec magictouch.js est disponible à l'adresse paulirish.com/demo/multi:

J'ai testé cette approche uniquement avec Chrome 10, mais elle devrait fonctionner sur d'autres navigateurs récents avec seulement des ajustements mineurs.

Si votre ordinateur ne dispose pas de la saisie multipoint, vous pouvez simuler des événements tactiles à l'aide d'autres traceurs TUIO, tels que reacTIVision. Pour en savoir plus, consultez la page du projet TUIO.

Notez que vos gestes peuvent être identiques aux gestes à plusieurs doigts au niveau du système d'exploitation. Sous OS X, vous pouvez configurer des événements à l'échelle du système en accédant au volet des préférences du pavé tactile dans les préférences système.

À mesure que les fonctionnalités multitouch se généralisent dans les navigateurs mobiles, j'ai hâte de voir les nouvelles applications Web tirer pleinement parti de cette API enrichie.