I nuovi browser stanno migliorando l'esperienza touch dei siti, con Internet Explorer 10 possiamo farlo grazie ai gesture events. Non sono molti i passaggi necessari a rendere i nostri siti touch-friendly e sono quelli ci permettono di farli funzionare bene anche con diversi dispositivi di input. In questo articolo vedremo come questa nuova feature di IE10.
Un esempio di utilizzo di questi eventi legati alle gesture è il Browser Surface Test Drive:
La gestione di eventi touch complessi è possibile grazie all'introduzione di oggetti JavaScript chiamati gesture recognition objects. Possiamo aggiungere al nostro sito degli oggetti di tipo gesture, decidere quali puntatori utilizzare (mouse, stilo o touch screen) e destinare i gesture events a qualunque elemento desideriamo. Il browser poi calcolerà quale gesto è stato effettuato sulla pagina e farà scattare il relativo evento.
Ciò permette agli sviluppatori di costruire vere e proprie esperienze gestuali, che sarebbero impossibili su qualunque altro browser, incluse azioni concorrenti come ruotare, con le mani, di due pezzi di puzzle contemporaneamente. Diamo un'occhiata al codice.
Creare un Gesture Object
Il primo passo da compiere per gestire le gesture sul nostro sito è quello di istanziare un gesture object:
var myGesture = new MSGesture();
Poi dobbiamo dare alla gesture un elemento target. Sarà l'elemento al quale il browser si riferirà gli eventi e che determinerà le coordinate spaziali delle gesture.
elm = document.getElementById("someElement");
myGesture.target = elm;
elm.addEventListener("MSGestureChange", handleGesture);
Infine, diciamo al gesture object quali tipi di puntatori dovrà elaborare nel riconoscimento delle gesture:
elm.addEventListener("MSPointerDown", function (evt) {
// adds the current mouse, pen, or touch contact for gesture recognition
myGesture.addPointer(evt.pointerId);
});
Nota: non dimentichiamo che abbiamo bisogno di utilizzare la direttiva -ms-touch-action per indicare all'elemento di non eseguire il comportamento di default collegato alla gesture, come lo zoom e il pan, ma quello stabilito da noi. Ad esempio:
<style>
html {
-ms-touch-action: none;
}
</style>
Gestire i gesture events
Una volta che abbiamo definito un gesture object, il suo oggetto target ed almeno una tipologia di puntatore, esso inizierà ad inviare eventi. Ne abbiamo di due tipi:
- gesture statiche, eventi come il tocco (tap) o la sosta (hold) in una certa posizione dello schermo;
- gesture dinamiche, come il pizzico (pinch), la rotazione (rotate) o lo swipe.
Tap
La gesture più semplice e basilare da riconoscere è il tocco (tap). Quando viene riconosciuto un tap, scatta l'evento MSGestureTap sull'elemento target del geture object.
A differenza dell'evento click, la gesture tap scatta solo quando un utente tocca (o preme un bottone del mouse o tocca la penna) e rilascia (solleva il dito) senza effettuare movimenti. Questo è spesso utile se si vuole gestire la differenza tra il tocco su un elemento e il trascinamento (drag) di un elemento.
Premi e sosta (press and hold)
La azione di press and hold avviene quando un utente tocca lo schermo e solleva il dito solo dopo qualche istante senza spostarsi sullo schermo. Durante l'interazione di press & hold scatta l'evento MSGestureHold più di una volta scandendo le varie fasi della gesture.
element.addEventListener("MSGestureHold", handleHold);
function handleHold(evt) {
if (evt.detail & evt.MSGESTURE_FLAG_BEGIN) {
// BEGIN segnala l'inizio della gesture.
// Per la gesture Hold, ciò significa che l'utente sta premendo
// nello stesso posto già da qualche istante, sufficiente a
// definire la gesture come una press & hold completa una volta
// sollevato il dito.
}
if (evt.detail & evt.MSGESTURE_FLAG_END) {
// END indica la fine della gesture.
}
if (evt.detail & evt.MSGESTURE_FLAG_CANCEL) {
// CANCEL segnala che l'utente ha iniziato la gesture
// ma poi l'ha annullata.
// Per la gesture hold, questo accade quando un utente trascina
// via il dito prima di sollevarlo.
// Questo flag è inviato insieme al flag di END, indicando che è
// terminato il riconoscimento della gesture.
}
}
Gesture dinamiche (pinch, rotate, swipe e drag)
Le gesture dinamiche, come pinch o rotate, sono riportate sotto forma di trasformazioni simili alle trasformazioni CSS 2D. Per una gesture dinamica scattano tre eventi:
- MSGestureStart;
- MSGestureChange (scatta a ripetizione finché l'azione continua);
- MSGestureEnd.
Ogni evento contiene informazioni su scala (pinch), rotazione, transalzione e velocità.
Siccome le gesture dinamiche ritornano delle trasformazioni, è facile utilizzare MSGesture con le trasformazioni CSS 2D per manipolare un elemento come una foto o un pezzo di un puzzle. Per esempio possiamo effettuare ingrandimenti, rotazioni o spostare elementi come segue:
targetElement.addEventListener("MSGestureChange", manipulateElement);
function manipulateElement(e) {
// Decommenta il seguente codice per disabilitare l'effetto inerzia
// impostato di default per il riconoscimento delle gesture dinamiche
// if (e.detail == e.MSGESTURE_FLAG_INERTIA)
// return;
// Ottiene l'ultima trasformazione CSS dell'elemento
var m = new MSCSSMatrix(e.target.style.transform);
e.target.style.transform = m
.translate(e.offsetX, e.offsetY) // Sposta l'origine della trasformazione sotto il centro della gesture
.rotate(e.rotation * 180 / Math.PI) // Applica la rotazione
.scale(e.scale) // Applica il fattore di scala
.translate(e.translationX, e.translationY) // Applica la traslazione
.translate(-e.offsetX, -e.offsetY); // Rimette a posto l'origine della trasformazione
}
Le gesture dinamiche, come l'applicazione di un fattore di scala o la rotazione, si possono ottenere con il mouse ruotando la rotellina e premendo rispettivamente i tasti CTRL e MAIUSCOLO.
Link utili