Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 98 di 112
  • livello avanzato
Indice lezioni

Touch API

Creare app per il mobile sfruttando il modello di interazione touch, con le due principali API disponibili: Touch Events e Pointer Events.
Creare app per il mobile sfruttando il modello di interazione touch, con le due principali API disponibili: Touch Events e Pointer Events.
Link copiato negli appunti

Uno dei tratti distintivi del mondo mobile è la modalità di interazione basata prevalentemente sul tocco delle dita. Nella maggior parte dei casi, il contatto delle dita con un punto dello schermo di un dispositivo mobile può essere assimilato al clic del mouse della classica interazione tramite PC. Infatti la maggior parte dei browser mappa in modo automatico il tocco delle dita ad eventi del mouse.

Tuttavia il modello di interazione touch è più variegato e prevede diverse modalità di tocco dello schermo come anche l'utilizzo di più dita contemporaneamente. Basti pensare alle ormai comuni gesture di swipe, zoom e pinch o alla rotazione di elementi.

Limitarsi a gestire l'interazione mobile con un sito o un'applicazione tramite i classici eventi del mouse è un approccio troppo semplicistico che penalizza l'esperienza utente.

Allo stato attuale sono previste due API standardizzate per la gestione dell'interazione touch:

  • Touch Events, nata da una proposta di Apple, prevede la gestione di una serie di eventi specifici per l'interazione touch;
  • Pointer Events, proposta da Microsoft, tende ad unificare le modalità di interazione proponendo un'API unica per mouse, dita, penne ed eventuali altri dispositivi di puntamento che potranno apparire sul mercato in futuro.

Purtroppo il supporto diretto di entrambe le API da parte dei browser più diffusi non è attualmente uniforme, anche se esistono diverse librerie che le emulano consentendone di fatto l'utilizzo anche se non in maniera nativa.

Touch events

L'API Touch events, come abbiamo accennato prima, si concentra sull'interazione tramite il tocco delle dita su un touch screen. Essa introduce quattro eventi specifici:

Evento Descrizione
touchstart Si verifica al primo contatto del dito con un elemento del DOM
touchend Si verifica quando il dito non è più in contatto con l'elemento del DOM
touchmove Si verifica quando il dito si sposta sullo schermo mantenendo il contatto
touchcancel Si verifica in presenza di una condizione per cui è necessario annullare l'evento touch, ad esempio quando sullo schermo sono presenti più punti di contatto di quanti il dispositivo è in grado di supportare

La gestione di ciascun evento viene fatto nel solito modo. Ad esempio, il seguente codice colora di rosso lo sfondo di un <div> presente su una pagina Web non appena viene toccato e ripristina il suo colore originario quando termina il contatto:

var coloreOriginario;
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("touchstart", function() {
	coloreOriginario = myDiv.style.backgroundColor;
	myDiv.style.backgroundColor = "red";
});
myDiv.addEventListener("touchend", function() {
	myDiv.style.backgroundColor = coloreOriginario;
});

Al verificarsi dell'evento, il gestore riceve alcune informazioni supplementari tramite l'oggetto event che consentono di definire il contesto dell'interazione. Ad esempio, il seguente codice consente di spostare l'elemento selezionato con il tocco di un solo dito:

var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("touchmove", function(event) {
	var touch;
	if (event.targetTouches.length == 1) {
		touch = event.targetTouches[0];
		myDiv.style.top = touch.pageY + "px";
		myDiv.style.left = touch.pageX + "px";
	}
});

Analizzando il codice dell'esempio notiamo che viene controllata la lunghezza dell'array targetTouches. Questo array contiene le informazioni relative a tutti i punti di contatto con la superficie dello schermo occupata dall'elemento nel momento in cui si è verificato l'evento. Nel caso specifico viene controllato che ci sia un solo punto di contatto. Se ci fossero più dita sul nostro <div> lo spostamento non verrebbe abilitato. Quindi, dopo aver fatto questa verifica preliminare, estraiamo le informazioni sul punto di contatto dall'array targetTouches ed utilizziamo le sue coordinate per modificare la posizione del nostro elemento.

Oltre alla proprietà targetTouches, l'oggetto event relativo ad eventi touch mette a disposizione altre due proprietà:

Proprietà Descrizione
touches Rappresenta l'insieme dei punti di contatto presenti sullo schermo (quindi non solo relativi all'elemento corrente)
changedTouches Indica l'insieme dei punti di contatto cambiati, ad esempio l'insieme dei punti di contatto rimossi in corrispondenza dell'evento touchend

Ciascun elemento di questi array è un oggetto Touch che rappresenta le informazioni relative a ciascun punto di contatto, tra cui un identificatore (identifier) e le coordinate del punto di contatto rispetto alla finestra (clientX, clientY), rispetto alla pagina (pageX, pageY) o allo schermo (screenX, screenY).

Multi-touch con i Touch events

Il seguente è un esempio di gestione multi-touch. Su un elemento di tipo <canvas> individuiamo tutti i punti di contatto evidenziandoli con dei cerchi rossi:

var myCanvas = document.getElementById("myCanvas");
var context = myCanvas.getContext("2d");
context.strokeStyle = "rgb(255, 0, 0)";
myCanvas.addEventListener("touchstart", function(event) {
	var touch;
	for (var i = 0; i < event.targetTouches.length; i++) {
		touch = event.targetTouches[i];
		context.beginPath();
		context.arc(touch.pageX, touch.pageY, 20, 0, 2*Math.PI, true);
		context.fill();
		context.stroke();
	}
});

Naturalmente, se non gestiamo opportunamente l'evento touchend i cerchi rimangono sullo schermo.

Pointer events

L'approccio proposto dai Pointer events mette a disposizione una serie di eventi che possono essere generati indifferentemente da qualsiasi dispositivo di puntamento: mouse, dita, penna. In pratica, lo sviluppatore dovrà gestire sempre lo stesso evento indipendentemente dal dispositivo che lo ha generato. Abbiamo quindi a disposizione i seguenti eventi:

Evento Descrizione
pointerdown si verifica quando viene avviata l'interazione e può essere avviato da situazioni diverse in base al tipo di dispositivo: viene premuto almeno un pulsante del mouse, avviene il primo contatto tra lo schermo e un dito o una penna
pointerenter si verifica quando un dispositivo di puntamento entra nell'area occupata da un elemento della pagina; l'evento non prevede la fase di bubbling
pointerleave si verifica quando un dispositivo di puntamento lascia l'area occupata da un elemento; l'evento non prevede la fase di bubbling
pointermove si verifica quando un dispositivo di puntamento si sposta
pointerout si verifica quando un dispositivo di puntamento entra nell'area occupata da un elemento della pagina; è analogo a pointerleave, ma prevede la fase di bubbling
pointerover si verifica quando un dispositivo di puntamento entra nell'area occupata da un elemento della pagina; è analogo a pointerenter, ma prevede la fase di bubbling
pointerup si verifica quando viene interrotta l'interazione, cioè quando viene rilasciato il pulsante del mouse o quando non c'è più contatto tra schermo e dispositivo di puntamento

Gli eventi richiamano praticamente gli stessi eventi previsti per il mouse (mousedown, mouseenter, ecc.) ed in effetti essi coincidono con questi nel caso in cui il dispositivo di puntamento utilizzato dall'utente sia proprio il mouse. In particolare, valgono per gli eventi pointerenter e pointerleave le considerazioni sulla propagazione dell'evento viste a suo tempo per gli eventi mouseenter e mouseleave.

Possiamo a questo punto ridefinire il primo esempio visto per i Touch events in termini di Pointer events nel seguente modo:

var coloreOriginario;
var myDiv = document.getElementById("myDiv");
myDiv.addEventListener("pointerdown", function() {
	coloreOriginario = myDiv.style.backgroundColor;
	myDiv.style.backgroundColor = "red";
});
myDiv.addEventListener("pointerup", function() {
	myDiv.style.backgroundColor = coloreOriginario;
});

Il codice sarà valido indipendentemente dal dispositivo di puntamento utilizzato per l'interazione con lo schermo.

L'oggetto event passato al gestore dell'evento prevede, oltre alle proprietà che consentono di individuare le coordinate del punto di contatto (clientX, clientY, ecc.), le seguenti proprietà che consentono di avere maggiori informazioni sul dispositivo di puntamento e sul punto di contatto:

Proprietà Descrizione
height altezza in pixel del punto di contatto
width largezza in pixel del punto di contatt
isPrimary consente di individuare un punto di contatto come primario in un contesto multi-touch
pointerId è l'identificatore univoco del punto di contatto
pointerType indica se il punto di contatto è stato generato da un mouse ("mouse"), una penna ("pen") o un dito ("touch")
pressure esprime il grado di pressione del punto di contatto sullo schermo tramite un valore decimale che va da zero (pressione minima) a uno (pressione massima)

Multi-touch con i Pointer events

Proviamo ad adeguare ai Pointer events l'esempio di gestione multi-touch visto per i Touch events. Ricordiamo che si tratta di evidenziare su un elemento di tipo <canvas> tutti i punti di contatto tramite dei cerchi rossi.

A differenza dei Touch events, dove più punti di contatto contribuiscono a generare un unico evento touchstart, nel contesto dei Pointer events ciascun punto di contatto genera un proprio evento pointerdown. Il codice che genera i cerchi rossi in corrispondenza di ciascun punto di contatto sarà quindi quello mostrato di seguito:

var myCanvas = document.getElementById("myCanvas");
var context = myCanvas.getContext("2d");
context.strokeStyle = "rgb(255, 0, 0)";
myCanvas.addEventListener("pointerdown", function(event) {
	context.beginPath();
	context.arc(event.pageX, event.pageY, 20, 0, 2*Math.PI, true);
	context.fill();
	context.stroke();
});

A differenza del caso dei Touch events, non abbiamo bisogno di iterare sull'elenco dei punti di contatto associati all'evento dal momento che ciascun punto di contatto è indipendente dall'altro nella generazione degli eventi. Vediamo inoltre come l'oggetto event passato come argomento al gestore di evento contiene direttamente le informazioni sul punto di contatto, nel caso specifico le coordinate di contatto.

In un contesto multi-touch potremmo avere la necessità di prendere in considerazione un solo punto di contatto e di ignorare gli altri. Supponiamo ad esempio di non voler considerare tutti i punti di contatto nell'esempio precedente ma di voler disegnare un solo cerchio rosso. Dal momento che tutti i punti di contatto genereranno un evento pointerdown, come facciamo a prenderne in considerazione uno soltanto ed ignorare gli eventi generati dagli altri punti di contatto?

Possiamo ottenere questo risultato sfruttando la proprietà isPrimary che ci sonsente di rilevare quale punto di contatto è considerato primario. Per il mouse è considerato primario l'unico puntatore mentre per penne e touch è considerato primario il primo contatto con lo schermo.

Sarà sufficiente quindi effettuare un semplice controllo su questa proprietà come mostrato di seguito:

myCanvas.addEventListener("pointerdown", function(event) {
	if (event.isPrimary) {
		context.beginPath();
		context.arc(event.pageX, event.pageY, 20, 0, 2*Math.PI, true);
		context.fill();
		context.stroke();
	}
});

Sottolineiamo ancora una volta che il codice di gestione dei Pointer events è valido indipendentemente dalla sorgente del punto di contatto.

Ti consigliamo anche