Nel febbraio del 2013 il W3C ha pubblicato l'ultima bozza della Specifica Pointer Event: una tappa importante del percorso di standardizzazione di una API ideata per consentire agli sviluppatori di creare applicazioni incentrate sull'uso dei dispositivi di input di ultima generazione, quali schermi touch, penne e mouse.
La notizia positiva è che tale API è già utilizzabile in IE10, incluso in Windows 8, e nelle applicazioni Windows Store.
Per un assaggio delle sue potenzialità, potete sperimentare e divertirvi con queste applicazioni:
Principi di funzionamento
L'elemento centrale della Pointer Event API è il pointer: non si tratta di un'astrazione di un particolare tipo di dispositivo di input, ma si riferisce a qualsiasi punto di contatto tra un generico dispositivo e lo schermo, sia esso una penna, un dito o il cursore del mouse.
In modo del tutto simile ai classici eventi del mouse, anche il "pointer" possiede i propri, di cui riporto quelli principali:
Evento | Descrizione |
---|---|
pointer down |
si verifica quando avviene il contatto con il dispositivo, ad esempio premendo il pulsante del mouse, toccando lo schermo o appoggiando la penna. |
pointer move |
si verifica quando cambiano le coordinate del puntatore, lo stato dei pulsanti premuti, la quantità di pressione effettuata, l'inclinazione, la superficie di contatto e così via, in base al tipo di dispositivo. |
pointer up |
si verifica quando viene a mancare il contatto con il dispositivo, ad esempio rilasciando il pulsante del mouse, oppure sollevando il dito o la penna dallo schermo. |
pointer over |
si verifica quando il puntatore viene spostato all'interno dell'area occupata da un elemento attivo (ad esempio, una figura, un pulsante o un generico elemento HTML).; |
pointer out |
si verifica quando il puntatore viene spostato all'esterno dell'area di un elemento attivo, oppure quando esce dalla zona in cui l'applicazione è in grado di rilevarne le azioni. |
pointer cancel |
si verifica quando è lecito non attendersi altri eventi su un puntatore o quando questo diventa inutilizzabile, ad esempio nel caso in cui si modifichi l'orientamento del dispositivo durante un'azione di tocco o utilizzando più dita di quelle supportate dal dispositivo, superando quindi i limiti imposti dall'hardware. |
Ad esclusione del mouse, è genericamente possibile avere più di un puntatore attivo sullo schermo, come nel caso di smartphone e tablet con supporto multi-touch: in questo contesto, viene generato un evento differente per ciascun puntatore, consentendo di gestire agevolmente l'azione nel suo complesso. IE10 mantiene una sorta di retrocompatibilità, riproducendo anche gli eventi relativi alla gestione tradizionale del mouse, che corrispondono e seguono gli eventi specifici della Pointer API.
Programmare con la Pointer API
Vediamo come è possibile sfruttare l'implementazione Microsoft della Pointer API presente su IE10. La prima operazione da fare è verificare la presenza del supporto alla Pointer API scrivendo questo codice JavaScript:
if (window.navigator.msPointerEnabled) {
// Pointer API disponibile e abilitata
}
Occorre tenere presente che la condizione rileva solamente la disponibilità dell'API e non la presenza fisica di un particolare device di input, touch, penna o mouse che sia.
Qui di seguito è riportato il codice completo di una pagina che permette di disegnare in un Canvas HTML5 muovendo il puntatore:
<!DOCTYPE html>
<html>
<head>
<title>Scribble touch example</title>
<style>
html {
-ms-touch-action: none; /* Disabilita la gestione automatica del browser */
}
</style>
<script>
window.addEventListener('load', function () {
var canvas = document.getElementById("drawSurface"), context = canvas.getContext("2d");
if (window.navigator.msPointerEnabled) {
canvas.addEventListener("MSPointerMove", paint, false);
}
else {
canvas.addEventListener("mousemove", paint, false);
}
function paint(event) {
// Disegna un piccolo rettangolo ogni volta che si verifica l'evento
context.fillRect(event.clientX, event.clientY, 5, 5);
}
});
</script>
</head>
<body>
<canvas id="drawSurface" width="500px" height="500px" style="border: solid 1px #000">
Canvas isn't supported by this browser or document mode
</canvas>
</body>
</html>
Questo è il risultato visibile all'interno del browser, muovendo il mouse o toccando lo schermo nel riquadro:
Nel codice della pagina possiamo notare l'attributo -ms-touch-action che permette di disabilitare le funzioni supportate nativamente da IE10 (panning e zooming automatico, visualizzazione del menu contestuale e selezione del testo), indicando al browser che intendiamo prendere il controllo e gestire autonomamente gli eventi di puntamento all'interno della pagina.
Troviamo inoltre una tecnica di fallback che associa l'operazione di disegno ai "classici" eventi del mouse qualora il supporto alla Pointer API non sia presente.
Vi sono poi script specifici per testare le caratteristiche dell'hardware:
// Verifica la presenza di hardware con supporto touch
if(navigator.msMaxTouchPoints) { ... }
// Verifica la presenza di hardware con supporto multi-touch
if(navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) { ... }
// Determina il numero massimo di punti di touch supportati dall'hardware
var touchPoints = navigator.msMaxTouchPoints;
È possibile supportare più tipi eterogenei di dispositivi all'interno della propria applicazione, ad esempio per l'esecuzione su touchscreen che consentono di agire simultaneamente sia con le dita che con una penna, discriminando il tipo di device che esegue l'azione:
<style>
#foo
{
width: 500px;
height: 500px;
background-color: red;
-ms-touch-action: none; /* Disabilita la gestione automatica del touch */
}
</style>
<div id="foo"></div>
<script>
function handleEvent(event) {
// Cambia il colore del DIV in base al tipo di dispositivo rilevato
switch (event.pointerType) {
case event.MSPOINTER_TYPE_TOUCH:
event.target.style.backgroundColor = "blue"; // Stai usando un touchscreen
break;
case event.MSPOINTER_TYPE_PEN:
event.target.style.backgroundColor = "green"; // Stai usando una penna
break;
case event.MSPOINTER_TYPE_MOUSE:
event.target.style.backgroundColor = "yellow"; // Stai usando il mouse
break;
}
}
document.getElementById("foo").addEventListener("MSPointerMove", handleEvent, false);
</script>
Microsoft ha affiancato al supporto della Pointer API anche il riconoscimento automatico delle gesture, come l'azione di riduzione tramite il tipico "pinch" (pizzico), di ingrandimento (zoom), di rotazione e così via. Nell'esempio che segue, l'elemento div
viene ridimensionato impostando l'apposita proprietà, in base al valore acquisito dalla gesture eseguita dall'utente:
<style>
html
{
overflow: hidden;
-ms-content-zooming: none; /* Disable pan/zoom */
}
#foo
{
background-color: red;
width: 500px;
height: 500px;
-ms-transform-origin: 50%;
-ms-transform-origin: 50%;
}
</style>
<div id="foo"></div>
<script>
function handleEvent(event) {
event.target.style.msTransform = "scale(" + event.scale + ")";
}
document.getElementById("foo").addEventListener("MSGestureChange", handleEvent, false);
</script>
Utilizzando le trasformazioni CSS3 sugli elementi, è possibile ottenere effetti ancora più complessi e fluidi.
>> Scopri di più sulle Trasformazioni CSS3
Altrettanto utile e ampiamente utilizzato è l'evento MSGestureTap, che consente di rilevare il click oppure il classico tocco singolo con il dito o con la penna.
Conclusioni e approfondimenti
La specifica W3C Pointer Events in corso di stesura si rivela una risorsa molto importante per gli sviluppatori che intendono creare applicazioni in grado di gestire efficacemente e in modo uniforme i moderni device di input, siano essi basati su touch, penne o altri tipi di "puntatori", quando eseguite all'interno di un browser recente che la supporti.
Sia che sviluppiamo applicazioni Windows Store o applicazioni Web possiamo sfruttare l'implementazione introdotta da Microsoft in IE10, intercettando gli eventi specifici previsti dall'API tramite codice JavaScript (reference: MSPointerEvent object), godendo del supporto automatico di alcune funzionalità fornite "out of the box" dal browser (come lo zoom e il panning), eventualmente disabilitabili tramite stili CSS se si desidera il controllo completo delle azioni, a cui si affiancano gli eventi legati alle gesture (reference: MSGestureEvent object).