L'accesso al Web da parte dei dispositivi mobili ha fatto emergere l'esigenza di dover gestire nelle pagine HTML situazioni prima non contemplate, come la rotazione dello schermo, l'interazione touch, la geolocalizzazione, ecc. Queste nuove esigenze hanno indotto il W3C a definire una serie di specifiche per consentire la gestione tramite JavaScript di funzionalità tipiche del mondo mobile.
Esploriamo in questa sezione le modalità di gestione di queste funzionalità con JavaScript.
Una delle prime problematiche che si presentano nel mondo mobile è la gestione dell'orientamento del dispositivo. Mentre per un classico PC possiamo assumere che una pagina Web venga vista con un orientamento stabile dello schermo, un dispositivo mobile può trovarsi in posizione verticale (portrait) o orizzontale (landscape) e può ruotare liberamente nello spazio anche durante la navigazione. Questo comporta da un lato la necessità di adeguare dinamicamente i contenuti di una pagina all'orientamento corrente dello schermo, dall'altro l'ideazione di nuove funzionalità prima non concepibili, come ad esempio giochi di abilità basati sull'equilibrio o modalità di interazione basate sul movimento del dispositivo
Possiamo sfruttare le Device Orientation API di JavaScript con cui intercettare non solo il cambio di orientamento, ma anche il movimento e l'accelerazione di un dispositivo.
DeviceOrientationEvent
Per individuare i cambi di orientamento del dispositivo possiamo sfruttare l'evento DeviceOrientationEvent generato dall'accelerometro. La prima cosa da fare è verificare se l'evento è supportato e in caso affermativo assegnare un gestore d'evento:
if (window.DeviceOrientationEvent) {
window.addEventListener("deviceorientation", handleOrientation);
}
La funzione handleOrientation
sarà invocata tutte le volte che viene intercettata una variazione dell'orientamento del dispositivo. Ad essa viene passato l'oggetto event
contenente informazioni sull'orientamento corrente rappresentate da quattro proprietà:
- absolute
- alpha
- beta
- gamma
La proprietà absolute è una proprietà booleana che indica il sistema di coordinate da prendere in considerazione:
- se il suo valore è
true
indica che il sistema di coordinate da considerare è quello terrestre, cioè quello che considera il centro della terra come origine, l'asse X parallelo alla superficie terrestre e orientato verso est, l'asse Y parallelo alla superficie terrestre e orientato verso nord e l'asse Z perpendicolare alla superficie terrestre e orientato verso l'alto; - se invece il valore è
false
, il sistema di coordinate è basato sul dispositivo stesso, con l'origine coincidente con il centro del dispositivo, l'asse X parallelo allo schermo e orientato verso destra, l'asse Y parallelo allo schermo e orientato verso l'alto e l'asse Z perpendicolare allo schermo e orientato fuori dal dispositivo.
Ecco il sistema di coordinate relativo al device (quando absolute è false):
Le altre tre proprietà descrivono la posizione del dispositivo espressa in gradi rispetto al sistema di coordinate adottato. In particolare, la proprietà alpha indica la rotazione del dispositivo intorno all'asse Z con un valore che va da 0
a 360
gradi:
La proprietà beta rappresenta lo spostamento intorno all'asse X con un valore che va da -180
a 180
gradi:
la proprietà gamma indica la rotazione del dispositivo intorno all'asse Y con un valore che va da -90
a 90
gradi:
Ad esempio, considerando il sistema di coordinate relativo al dispositivo, i seguenti valori indicano la rotazione di 45
gradi verso destra del lato destro, cioè il lato destro che si abbassa di 45
gradi e il lato sinistro che si alza di 45
gradi:
{ alpha: 0, beta: 0, gamma: 45 }
Il seguente esempio mostra i valori relativi all'orientamento del dispositivo e ruota un'immagine in funzione di questi parametri applicando la proprietà CSS transform
:
function handleOrientation(event) {
document.getElementById("absolute").innerHTML = event.absolute;
document.getElementById("alpha").innerHTML = event.alpha;
document.getElementById("beta").innerHTML = event.beta;
document.getElementById("gamma").innerHTML = event.gamma;
document.getElementById("image").style.transform = "rotate(" + event.gamma + "deg) rotate3d(1,0,0," + (event.beta*-1) + "deg)";
}
In modo analogo all'orientamento del dispositivo possiamo intercettare e gestire alcuni dettagli sul suo movimento. Ci viene in aiuto in questo caso l'evento DeviceMotionEvent
:
if (window.DeviceMotionEvent) {
window.addEventListener("devicemotion", handleMotion);
}
Come possiamo vedere, la modalità di intercettazione dell'evento è quella solita. Al verificarsi di un movimento del dispositivo verrà generato l'evento devicemotion
ed invocata la funzione di callback handleMotion
a cui sarà passato l'oggetto event
con le seguenti informazioni:
Proprietà | Descrizione |
---|---|
acceleration | questa proprietà riporta l'accelerazione registrata dal dispositivo espressa in metri per secondo quadrato (m/s2); essa è rappresentata da un oggetto con le proprietà x , y , e z rappresentanti rispettivamente l'asse da ovest verso est, l'asse da sud a nord e l'asse perpendicolare alla terra |
accelerationIncludingGravity | questa proprietà è analoga alla precedente, ma include nell'accelerazione del dispositivo anche l'accelerazione di gravità |
rotationRate | rappresenta la velocità di rotazione intorno a ciascun asse espresso in gradi al secondo; le sue proprietà alpha , beta e gamma corrispondono a quanto visto a proposito dell'orientamento del dispositivo |
interval | indica l'intervallo di tempo in millisecondi di rilevazione del movimento da parte dell'hardware del dispositivo |
Per comprendere la differenza tra la proprietà acceleration
e la proprietà accelerationIncludingGravity
, consideriamo un dispositivo non in movimento posato su un tavolo. La proprietà acceleration
sarà rappresentata dal seguente oggetto:
{ x: 0, y: 0, z: 0 }
Non c'è nessun movimento, quindi nessuna accelerazione.
La proprietà accelerationIncludingGravity
sarà invece rappresentata dal seguente oggetto:
{ x: 0, y: 0, z: 9.81 }
Pur essendo fermo, il dispositivo è soggetto alla forza di gravità sull'asse Z.
Nel seguente esempio sfruttiamo le informazioni sul movimento del dispositivo per scorrere una sequenza di immagini:
function handleMotion(event) {
var img = document.getElementById("immagine");
if (event.accelerationIncludingGravity.x < -10) {
currentImageIndex = (currentImageIndex + 1)%imageList.length;
img.src = imageList[currentImageIndex];
}
if (event.accelerationIncludingGravity.x > 10) {
currentImageIndex = (currentImageIndex - 1 + imageList.length)%imageList.length;
img.src = imageList[currentImageIndex];
}
}
Nell'esempio supponiamo che l'array imageList
contenga l'elenco degli URL delle immagini e che la variabile currentImageIndex
rappresenti l'indice dell'immagine corrente. Quando il dispositivo viene scosso verso destra con un'accelerazione superiore all'accelerazione di gravità viene visualizzata l'immagine successiva, se invece viene scosso verso sinistra con un'analoga intensità viene visualizzata l'immagine precedente.
Link utili
- Specifica delle Device Orientation API