Développement Web multitouch

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 doivent pouvoir gérer ces événements. Par exemple, presque tous les jeux rapides exigent que le joueur appuie sur plusieurs boutons à la fois, ce qui, dans le contexte d'un écran tactile, implique le multipoint.

Apple a lancé son API d'événements tactiles dans iOS 2.0. Android rattrape cette norme de facto et réduit l'écart. Récemment, un groupe de travail du W3C s'est réuni pour travailler sur cette spécification des événements tactiles.

Dans cet article, je vais vous présenter l'API d'événements tactiles fournie par les appareils iOS et Android, ainsi que Chrome pour ordinateur sur du matériel compatible avec le tactile. Je vais également vous expliquer les types d'applications que vous pouvez créer, vous présenter quelques bonnes pratiques et vous expliquer des techniques utiles pour développer plus facilement des applications compatibles avec le tactile.

Événements tactiles

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

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

Chaque événement tactile comprend trois listes de gestes:

  • touches : liste de tous les doigts actuellement sur l'écran.
  • targetTouches : liste des 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 qui a été retiré.

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

  • identifier : nombre qui identifie de manière unique le doigt actuel dans la session tactile.
  • target : élément DOM qui était la cible de l'action.
  • Coordonnées client/page/écran : emplacement de l'action sur l'écran.
  • radius coordinates et rotationAngle : décrivent l'ellipse qui se rapproche de la forme du doigt.

Applications compatibles avec l'écran tactile

Les événements touchstart, touchmove et touchend offrent un ensemble de fonctionnalités suffisamment riche pour prendre en charge pratiquement tous les types d'interactions tactiles, y compris tous les gestes multipoint habituels tels que le pincement pour zoomer, la rotation, etc.

Cet extrait de code 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 toutes les interactions actuelles à l'écran. Il est utile simplement de se faire une idée 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émonstrations multipoint intéressantes sont déjà disponibles, comme cette démonstration de dessin sur canevas réalisée par Paul Irish et d'autres.

Capture d&#39;écran du dessin

Et Browser Ninja, une démonstration technologique qui est un clone de Fruit Ninja utilisant des transformations et des transitions CSS3, ainsi que du canevas :

Ninja du navigateur

Bonnes pratiques

Empêcher le zoom

Les paramètres par défaut ne fonctionnent pas très bien avec les gestes multipoint, car vos balayages et 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 afin qu'elle ne soit pas évolutive pour l'utilisateur à l'aide de la balise méta suivante :

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

Pour en savoir plus sur la configuration de votre vue, consultez cet article sur le HTML5 pour mobile.

Empêcher le défilement

Certains appareils mobiles présentent des comportements par défaut pour le mouvement tactile, comme l'effet de défilement excessif classique d'iOS, qui fait rebondir la vue lorsque le défilement dépasse les limites du contenu. Cela peut prêter à confusion dans de nombreuses applications multipoint et peut être facilement désactivé :

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

Rendre le rendu avec précaution

Si vous écrivez une application multipoint impliquant des gestes à plusieurs doigts complexes, faites attention à la façon dont vous réagissez aux événements tactiles, car vous en gérerez beaucoup à la fois. Prenons l'exemple de la section précédente, qui dessine toutes les interactions sur l'écran. Vous pouvez dessiner dès qu'il y a une entrée tactile :

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

Cependant, cette technique ne s'adapte pas au nombre de doigts sur l'écran. Vous pouvez plutôt 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 indiquant TOUS les doigts en contact avec l'écran, et pas uniquement ceux qui se trouvent sur la cible de l'élément DOM. Vous trouverez peut-être beaucoup plus utile d'utiliser event.targetTouches ou event.changedTouches à la place.

Enfin, comme vous développez pour mobile, vous devez connaître les bonnes pratiques générales pour les mobiles, qui sont abordées dans cet article d'Eric Bidelman et dans ce document du W3C.

Vérifier si l'appareil est compatible

Malheureusement, les implémentations d'événements tactiles varient considérablement en termes d'exhaustivité et de qualité. 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 matériel Nexus One et Nexus S, Android 3.0.1 sur Xoom et iOS 4.2 sur iPad et iPhone.

En résumé, 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é n'est compatible avec ces événements:

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

Dans chaque liste de contact, les navigateurs testés fournissent également les listes de contact touches, targetTouches et changedTouches. Toutefois, aucun des navigateurs testés n'est compatible avec radiusX, radiusY ou rotationAngle, qui spécifient 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 le multipoint. Il s'agit d'un problème connu.

Android 3.0.1 (Xoom)

Le navigateur de Xoom est compatible avec la technologie 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, le code suivant réagira à 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);

En revanche, les éléments suivants ne sont pas acceptés :

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, peuvent suivre un grand nombre de doigts et offrent une expérience tactile très réactive dans le navigateur.

Outils pour les développeurs

En développement mobile, il est souvent plus simple de commencer le prototypage sur ordinateur, puis de s'attaquer aux parties spécifiques aux mobiles sur les appareils que vous prévoyez de prendre en charge. La multipoint est l'une des fonctionnalités difficiles à tester sur un PC, car la plupart des PC ne disposent pas d'une entrée tactile.

Le fait d'avoir à effectuer des tests sur mobile peut rallonger votre cycle de développement, car chaque modification que vous apportez doit être transmise à un serveur, puis chargée sur l'appareil. Ensuite, une fois l'application exécutée, vous ne pouvez pas faire grand-chose pour la déboguer, car les tablettes et les smartphones ne disposent pas d'outils de développement Web.

Pour résoudre ce problème, vous pouvez simuler des événements tactiles sur votre ordinateur de développement. Pour les gestes tactiles uniques, les événements tactiles peuvent être simulés en fonction des événements de la souris. Les événements multipoint peuvent être simulés si vous disposez d'un appareil avec entrée tactile, comme un MacBook Apple moderne.

Événements à un seul geste

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

Pour les autres navigateurs, vous pouvez essayer Phantom Limmb, qui simule des événements tactiles sur les pages et donne également une immense main au démarrage.

Il existe également le plug-in jQuery Touchable qui unifie les événements tactiles et ceux de la souris sur les différentes plates-formes.

Événements multipoint

Pour permettre à votre application Web multipoint de fonctionner dans votre navigateur sur votre pavé tactile multipoint (comme un MacBook Apple ou un MagicPad), j'ai créé le polyfill MagicTouch.js. Il capture les événements tactiles de votre pavé tactile et les convertit en événements tactiles compatibles avec les normes.

  1. Téléchargez et installez le plug-in NPAPI npTuioClient dans ~/Library/Internet Plug-Ins/.
  2. Téléchargez l'application TongSeng TUIO pour le MagicPad de Mac et 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 à partir de rappels npTuioClient.
  4. Incluez le script magictouch.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 sur paulirish.com/demo/multi :

Je n'ai testé cette approche qu'avec Chrome 10, mais elle devrait fonctionner avec d'autres navigateurs modernes avec seulement quelques ajustements mineurs.

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

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

À mesure que les fonctionnalités multipoint sont de plus en plus compatibles avec les navigateurs mobiles, je suis ravi de voir les nouvelles applications Web exploiter pleinement cette API riche.