Háptica en iOS
iPad, iPad, iPad… otro nuevo dispositivo para cautivar a los ávidos consumidores, pero que por lo menos trae interesantes nuevas tecnologías. Aparte de que crean que es un iPhone gigante, tiene varias innovaciones que permiten darle mucha rienda a la imaginación de los creadores de contenido específico para esta plataforma. Una de las que más me han interesados, corresponde a los eventos gestuales.
Este artículo abordará todos los eventos disponibles para iPad y que ocurren cuando el usuario interactúa con una página web en iOS. Aunque puedes visualizar los ejemplos con Safari 5 para escritorio o el mismo iPhone, la mejor interacción la puedes lograr desde un iPad mismo por la dimensión y calidad de su superficie táctil (o en su defecto con su simulador).
Eventos Multitouch
Puedes usar classes de eventos touch de tipo DOM en Javascript que ya están disponibles en iOS. Si quieres registrar estos eventos, el sistema envía objetos TouchEvent a aquellos elementos DOM mientras los dedos se mueven por sobre la superficie. Una secuencia multitouch comienza cuando un dedo toca por primera vez la superficie. La secuencia termina cuando el último de esos dedos se levanta de la misma superficie. Éstos eventos son similares a los usuales eventos de mouse, excepto que puedes tener toques simultáneos en la superficie en diferentes lugares de la misma. Un objeto de evento touch es utilizado para encapsular todos los toques que existen en un mismo momento en la pantalla. Cada dedo es representado por un objeto touch y las típicas propiedades que encuentras en un evento de mouse están en un evento touch, pero no el objeto mismo.
Cuatro son los principales eventos touch:
- ontouchstart
<dd>
ocurre cada vez que un dedo se posa sobre la pantalla.
</dd>
<dt>
ontouchmove
</dt>
<dd>
ocurre cuando un dedo que ya está en la pantalla se mueve sobre ella.
</dd>
<dt>
ontouchend
</dt>
<dd>
ocurre cada vez que un dedo sale de la pantalla.
</dd>
<dt>
ontouchcancel
</dt>
<dd>
el sistema puede cancelar los eventos en ciertas ocasiones, como por ej. cuando recibes un <strong>SMS</strong> mientras estás arrastrando un elemento.
</dd>
Para registrarlos con Javascript:
element.addEventListener("touchstart", touchStart, false);
element.addEventListener("touchmove", touchMove, false);
element.addEventListener("touchend", touchEnd, false);
element.addEventListener("touchcancel", touchCancel, false);
Y si lo quieres implementar como una función:
function touchStart(event) {
<span class="commentjs">// tomemos las coordenadas del dedo cuando toca la pantalla</span>
var x = event.touches[0].pageX;
var y = event.touches[0].pageY;
alert('X = '+x+',Y = '+y);
}
Un simple evento: arrastra un elemento cuando mueves el dedo:
function touchMove(event) {
event.preventDefault();
var touch = event.touches[0];
var node = touch.target;
node.style.position = "absolute";
node.style.left = touch.pageX + "px";
node.style.top = touch.pageY + "px";
}
Detalle: por defecto, si arrastras un dedo sobre la pantalla es probable que la página comience a moverse (peor si ésta tiene scroll). Por suerte agregaron la función preventDefault() que hace que la página se quede quieta si lo necesitamos.
Las listas de eventos agrupan estos objetos, y contiene información para cada dedo que está tocando la pantalla. Además, contiene 2 otras listas: una que tiene información para los dedos que se originan del mismo elemento y otro que contiene sólo información para los dedos asociados al mismo evento. Estas listas están disponibles para cada evento touch, y son:
- touches
<dd>
una lista para cada dedo que está posado actualmente sobre la pantalla.
</dd>
<dt>
targetTouches
</dt>
<dd>
tal como <strong>touches</strong>, pero filtra sólo la información para los dedos que comienzan del mismo elemento.
</dd>
<dt>
changedTouches
</dt>
<dd>
lista la información para cada dedo involucrado en el mismo evento.
</dd>
Las propiedades que contienen estas listas son:
- clientX
<dd>
coordenada X del toque relativa al <em>viewport</em> (pantalla visible).
</dd>
<dt>
clientY
</dt>
<dd>
coordenada Y del toque relativa al <em>viewport</em>.
</dd>
<dt>
screenX
</dt>
<dd>
coordenada X relativa a la pantalla.
</dd>
<dt>
screenY
</dt>
<dd>
coordenada Y relativa a la pantalla.
</dd>
<dt>
pageX
</dt>
<dd>
coordenada X relativa a la página completa (incluye <em>offset</em> del <em>scroll</em>).
</dd>
<dt>
pageY
</dt>
<dd>
coordenada Y relativa a la página completa.
</dd>
<dt>
target
</dt>
<dd>
elemento donde el evento touch fue originado.
</dd>
<dt>
indentifier
</dt>
<dd>
número identificados, único para cada evento <em>touch</em>.
</dd>
Para entender mejor, veamos el siguiente caso:
-
Cuando pongo un dedo en la pantalla, las 3 listas tendrán la misma información en sus propiedades, pero changedTouches fue el que originó el evento.
<li>
<p>
Cuando pongo el segundo dedo, <strong>touches</strong> tendrá 2 items (uno para cada dedo); <strong>targetTouches</strong> tendrá 2 items sólo si el segundo dedo es posado en el mismo elemento del primero; <strong>changedTouches</strong> tendrá información relacionada al segundo dedo, porque fue lo que causó el evento.
</p>
</li>
<li>
<p>
Si pongo 2 dedos exactamente al mismo tiempo, tendré 2 items en <strong>changedTouches</strong>: uno para cada dedo.
</p>
</li>
<li>
<p>
Si muevo mis dedos, la única lista que cambiará es <strong>changedTouches</strong> y va a tener información relacionada a cada dedo que se vaya moviendo (al menos uno).
</p>
</li>
<li>
<p>
Cuando levanto un dedo, será eliminado de <strong>touches</strong> y <strong>targetTouches</strong> y aparecerá en <strong>changedTouches</strong> ya que fue el que originó el evento.
</p>
</li>
<li>
<p>
Si quito el último dedo se vaciarán <strong>touches</strong> y <strong>targetTouches</strong>, y <strong>changedTouches</strong> tendrá la información para ese ultimo dedo.
</p>
</li>
Eventos Gestuales
<p>
Eventos <em>multitouch</em> pueden ser combinados para crear eventos de gestos. Los objetos <em>GestureEvent</em> son enviados durante una secuencia <em>multitouch</em> y contienen información de dimensiones y rotaciones.
</p>
<p>
Para registrarlos en <strong>HTML</strong>:
</p>
<div
ongesturestart="gestureStart(event);"
ongesturechange="gestureChange(event);"
ongestureend="gestureEnd(event);"
>
Y mediante Javascript:
element.addEventListener("gesturestart", gestureStart, false);
element.addEventListener("gesturechange", gestureChange, false);
element.addEventListener("gestureend", gestureEnd, false);
Comencemos con un ejemplo simple:
function gestureStart(event) {
<span class="commentjs">// tomamos el angulo y tamaño del elemento</span>
var angle = event.rotation;
var scale = event.scale;
alert('angulo: '+angle+', dimension: '+scale);
}
Ahora escalamos y rotamos un elemento:
function gestureChange(event) {
event.preventDefault();
event.target.style.width = (200 * event.scale) + "px";
event.target.style.height = (200 * event.scale) + "px";
event.target.style.webkitTransform = 'rotate(' + event.rotation + 'deg)';
}
Creo que esto es un buen comienzo para que te interese esta plataforma, la que implementa un tipo de interacción háptica poco usual y con un gran potencial comercial.