Desarrollo web con tecnología Multitouch

HTML5 Rocks

Introducción

Los dispositivos móviles como los smartphones y los tablets suelen tener una pantalla capacitiva sensible al tacto para reconocer las interacciones de los dedos de los usuarios con la pantalla. A medida que la Web para móviles evoluciona para poder ejecutar aplicaciones cada vez más sofisticadas, se hace necesario que los desarrolladores web dispongan de un método de gestión de estos eventos. Por ejemplo, los juegos que tienen un ritmo trepidante requieren que el jugador pulse varios botones a la vez, lo que, en el contexto de una pantalla táctil, implica el uso de la tecnología Multitouch.

Apple introdujo su API de eventos de toque en el sistema operativo iOS 2.0. Android ha estado trabajando para alcanzar este estándar de facto y acortar distancias con Apple. Recientemente, un grupo de trabajo del W3C también se ha reunido para trabajar en una especificación de eventos de toque.

En este artículo, profundizaremos en el API de eventos de toque de los dispositivos Android e iOS, investigaremos los tipos de aplicaciones que se pueden crear, examinaremos algunas prácticas recomendadas y veremos algunas técnicas útiles que pueden facilitar el desarrollo de aplicaciones táctiles.

Eventos de toque

En esta especificación se describen tres eventos de toque básicos que se han implementado en muchos dispositivos móviles:

  • touchstart: se coloca un dedo sobre un elemento DOM.
  • touchmove: se arrastra un dedo a lo largo de un elemento DOM.
  • touchend: se quita un dedo de un elemento DOM.

Cada evento de toque incluye tres listas de toques:

  • touches: indica una lista de todos los dedos con los que se está tocando la pantalla.
  • targetTouches: indica una lista de los dedos que están colocados sobre el elemento DOM actual.
  • changedTouches: indica una lista de los dedos que se utilizan en el evento actual. Por ejemplo, en un evento "touchend", será el dedo que se ha retirado.
Estas listas se componen de objetos que incluyen información de toque:
  • identifier: representa un número que identifica de forma exclusiva al dedo que se está utilizando en la sesión de toque.
  • target: representa el elemento DOM que constituye el destino de la acción.
  • client/page/screen coordinates: indica la parte de la pantalla en la que se lleva a cabo la acción.
  • radius coordinates y rotationAngle: describe la elipse que dibuja la forma del dedo.

Aplicaciones táctiles

Los eventos touchstart, touchmove y touchend ofrecen un conjunto de funciones lo suficientemente amplio como para admitir casi cualquier tipo de interacción táctil, incluidos todos los movimientos habituales que implican tocar varias veces la pantalla como pellizcar-ampliar, girar, etc.

Este fragmento permite arrastrar un elemento DOM con un solo dedo:

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

A continuación aparece un ejemplo en el que se muestran todos los toques empleados actualmente en la pantalla. Puede ser útil simplemente para conocer la capacidad de respuesta del dispositivo.

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

Demostraciones

Ya se encuentran disponibles una serie de interesantes demostraciones de la tecnología Multitouch, como esta demostración de dibujo basado en canvas creada por Paul Irish y otros autores.

También se puede consultar Browser Ninja, una demostración de tecnología análoga a la de Fruit Ninja que utiliza transiciones y transformaciones CSS3, así como el elemento canvas:

Prácticas recomendadas

Evitar el uso del zoom

La configuración predeterminada no funciona muy bien con la tecnología Multitouch, ya que los movimientos y desplazamientos se asocian frecuentemente a comportamientos del navegador, tales como el desplazamiento por la pantalla y la ampliación y reducción de la imagen.

Para inhabilitar el zoom, utiliza la siguiente metaetiqueta para configurar la ventana gráfica de forma que los usuarios no puedan realizar cambios:

<meta name="viewport" 
  content="width=device-width, initial-scale=1.0, user-scalable=no">
Para obtener más información sobre la configuración de la ventana gráfica, consulta este artículo sobre HTML5 para móviles.

Evitar el desplazamiento

Algunos dispositivos móviles tienen comportamientos predeterminados en relación con los eventos touchmove, como el clásico efecto de desplazamiento de iOS, que provoca un rebote cuando se exceden los límites del contenido al desplazarse por la pantalla. Este efecto es confuso en muchas aplicaciones con tecnología Multitouch y se puede inhabilitar fácilmente:

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

Tener cuidado con el resultado de los toques

Si vas a crear una aplicación con tecnología Multitouch que implica diferentes movimientos complejos con los dedos, te recomendamos que planees correctamente las reacciones que estos toques van a producir, ya que debes gestionar muchos de forma simultánea. Ten en cuenta el ejemplo de la sección anterior, en el que se representan todos los toques de la pantalla. Puedes dibujar tan pronto como exista actividad de toque:

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

No obstante, esta técnica no varía con el número de dedos que se tienen sobre la pantalla. En su lugar, puedes realizar un seguimiento de todos los dedos y representarlos en bucle para obtener un mejor rendimiento:

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

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

Sugerencia: el método "setInterval" no es adecuado para crear animaciones, ya que no tiene en cuenta el bucle de renderización del navegador. Los navegadores actuales para ordenador utilizan el método requestAnimationFrame, una opción mucho más adecuada tanto por el rendimiento como por el ahorro de batería. Este será el método preferente cuando se pueda utilizar en navegadores de dispositivos móviles.

Utilizar "targetTouches" y "changedTouches"

Ten en cuenta que "event.touches" representa el conjunto de TODOS los dedos que están en contacto con la pantalla, no solo aquellos que se encuentran sobre el elemento DOM de destino. Puede ser mucho más útil utilizar "event.targetTouches" o "event.changedTouches".

Por último, como desarrollador de aplicaciones para dispositivos móviles, debes tener en cuenta las prácticas generales recomendadas para dispositivos móviles que se incluyen en el artículo de Eric Bidelman y en este documento de W3C.

Dispositivos compatibles

Por desgracia, existen grandes diferencias en cuanto a exhaustividad y calidad en las diversas implementaciones de eventos de toque. He creado una secuencia de comandos de diagnóstico que incluye información básica sobre la implementación del API de toques (por ejemplo, los eventos compatibles y los resultados que se obtienen al ejecutar eventos "touchmove"). Las pruebas se realizaron en el sistema operativo Android 2.3.3 de los dispositivos Nexus One y Nexus S, en el sistema operativo Android 3.0.1 del dispositivo Xoom y en el sistema operativo iOS 4.2 de los dispositivos iPad y iPhone.

En resumen, todos los navegadores probados resultaron ser compatibles con los eventos touchstart, touchend y touchmove.

En la especificación se incluyen tres eventos de toque adicionales que no son compatibles con ninguno de los navegadores probados:

  • touchenter: un dedo en movimiento toca un elemento DOM.
  • touchleave: un dedo en movimiento deja de tocar un elemento DOM.
  • touchcancel: se interrumpe un toque (implementación específica).

En cada lista de toques, los navegadores probados proporcionan también las listas de toques touches, targetTouches y changedTouches. Sin embargo, ninguno de los navegadores probados admite el uso de los objetos "radiusX", "radiusY" y "rotationAngle", que especifican la forma del dedo que toca la pantalla.

Durante un evento "touchmove", los eventos se activan aproximadamente 60 veces por segundo en todos los dispositivos probados.

Android 2.3.3 (Nexus)

El navegador Android Gingerbread (probado en los dispositivos Nexus One y Nexus S) no es compatible con la tecnología Multitouch. Puedes obtener información sobre esta incidencia conocida en esta página.

Android 3.0.1 (Xoom)

El navegador del dispositivo Xoom ofrece una compatibilidad básica con la tecnología Multitouch, pero funciona solamente con un elemento DOM. El navegador no responde correctamente a dos toques simultáneos en diferentes elementos DOM. A continuación se muestra un fragmento de código con el que se puede conseguir una reacción a dos toques simultáneos:

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

Por el contrario, si se utiliza el siguiente código, no se producirá ninguna reacción:

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)

Los dispositivos iOS son totalmente compatibles con la tecnología Multitouch, pueden realizar un seguimiento de varios dedos y ofrecen una experiencia de toque muy interactiva en lo que respecta al navegador.

Herramientas para desarrolladores

En la programación para dispositivos móviles, a menudo resulta más fácil crear primero un prototipo para ordenador y, posteriormente, desarrollar las partes específicas para móviles en los dispositivos pertinentes. La tecnología Multitouch es una de esas funciones que difícilmente se pueden probar en ordenadores, dado que la mayoría de ellos no son táctiles.

Realizar pruebas en un dispositivo móvil puede alargar el ciclo de desarrollo, ya que todas las modificaciones que se efectúen deben enviarse a un servidor y cargarse posteriormente en el dispositivo. Una vez que se esté ejecutando la aplicación, no se puede hacer gran cosa para depurarla, ya que los tablets y los smartphones no tienen herramientas de desarrolladores web.

Una posible solución es simular eventos de toque en el ordenador de desarrollo. Los eventos de un solo toque se pueden simular con eventos de ratón. Los eventos de varios toques se pueden simular si se tiene un dispositivo táctil (por ejemplo, un MacBook de Apple).

Eventos de un solo toque

Si quieres simular eventos de un solo toque en tu ordenador, prueba Phantom Limb, que simula eventos de toque en páginas y también ofrece ayuda con el arranque.

También puedes utilizar Touchable, un complemento de jQuery que unifica eventos de toque y de ratón en diferentes plataformas.

Eventos de varios toques

Para poder utilizar una aplicación web de varios toques en el navegador de un touchpad con tecnología Multitouch (como un MacBook o un MagicPad de Apple), puedes utilizar el polyfill MagicTouch.js que he creado. Este fragmento de código permite capturar eventos de toque del touchpad y convertirlos en eventos de toque estándar compatibles.

  1. Descarga el complemento npTuioClient NPAPI e instálalo en ~/Library/Internet Plug-Ins/.
  2. Descarga la aplicación TongSeng TUIO para MagicPad de Mac e inicia el servidor.
  3. Descarga MagicTouch.js, una biblioteca JavaScript que sirve para simular eventos de toque compatibles con las especificaciones en función de devoluciones de llamadas de npTuioClient.
  4. Incluye la secuencia de comandos "magictouch.js" y el complemento "npTuioClient" en tu aplicación como se indica a continuación:
<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>

Aunque he probado estas sugerencias únicamente en Chrome 10, deberían funcionar en otros navegadores actuales efectuando solo algunos pequeños retoques.

Si tu ordenador no incluye tecnología Multitouch, puedes simular eventos de toque con otras herramientas TUIO de seguimiento del movimiento, como reacTIVision. Para obtener más información, consulta la página del proyecto TUIO.

Ten en cuenta que tus movimientos pueden ser idénticos a los movimientos que implican varios toques del sistema operativo. En OS X, puedes configurar eventos en todo el sistema mediante el "Panel de preferencia" del touchpad, que se incluye en "Preferencias del sistema".

Las funciones Multitouch son cada vez más compatibles con los navegadores de dispositivos móviles, así que estoy deseando ver cómo se aprovecha esta completa API en las nuevas aplicaciones web.

Comments

0