Pagine HTML5 fullscreen responsive con Adobe Animate

0
Share:

Come promesso, iniziamo a parlare di come ottimizzare un istant game realizzato con Adobe Animate per i dispositivi mobili. Nella fattispecie, useremo l’esempio pubblicato circa un mesetto fa come base di partenza per realizzare un puzzle game in HTML5 e createJS che gira su tutti i dispositivi. Poiché, rispetto alla primissima versione, ne ho approfittato per effettuare alcuni ritocchi, tra cui una nuova disposizione random dei pezzi e l’introduzione di un menu di regolazione, le cose da dire sono diventate parecchie. Quindi, per non scrivere un articolo chilometrico, ho deciso di suddividere il tutorial in più parti. In questa prima parte ci limiteremo a creare un fullscreen responsive che verifica l’orientamento dello schermo. Per vedere subito il risultato finale cliccate qui

Il documento di partenza

Il gioco prevede una serie di caratteristiche di cui dobbiamo tenere conto in fase progettuale. Prima di tutto, poiché l’ambiente di gioco sarà caratterizzato da uno schermo orientato in orizzontale, dobbiamo impostare le dimensioni dello stage nel pannello proprietà. Nel mio caso ho scelto  le dimensioni consigliate per i dispositivi android, ovvero una larghezza di 800 pixel e un’altezza di 480 pixel.  Si tratta di due valori non obbligatori (in teoria potremmo anche scegliere le dimensioni suggerite per i dispositivi mac, ovvero 960 per 640), infatti a facilitarci la vita sarà un codice attraverso il quale forzeremo lo spazio del tag canvas ad occupare tutto lo spazio del browser.
Finite le chiacchiere introduttive entriamo nel vivo. Se dopo aver scaricato il sorgente (trovate il link alla fine dell’articolo) lo aprite, potrete osservare cinque livelli.

full_fig1
I vari livelli, contandoli dal basso verso l’alto si chiamano: sfondo, logo, pulsanti. messaggio e azioni. Nel primo abbiamo una semplice jpg, nel secondo un logo animato, nel terzo due pulsanti, nel quarto un clip caratterizzato da una scritta informativa e nel quinto il codice createJS.
L’esempio prevede due pulsanti: p_start che attiva lo schermo in fullscreen e p_off che lo disattiva. Il primo pulsante oltre ad attivare il fullscreen aziona anche un’interpolazione movimento nella linea temporale dell’istanza clip1. Inoltre abbiamo un clip filmato msg caratterizzato da una scritta che consiglia all’utente di cambiare verso, nel caso in cui dovesse orientare il dispositivo verticalmente.  Quindi riepilogando:

  1. Quando l’utente si collega trova subito lo stage “spalmato” in modo responsive tramite un codice che vedremo tra breve.
  2. Per iniziare a giocare deve premere un pulsante centrale che attiva la modalità fullscreen e azione un clip filmato (nella versione finale darà il via al gioco).
  3. Volendo l’utente potrà uscire dalla modalità fullscreen tramite un tasto apposito (nella versione finale ci sarà un menu con varie opzioni tra cui un tasto di uscita).

Useremo questo meccanismo nel puzzle ottimizzato per i dispositivi mobili di cui parleremo nel prossimo articolo.

Rendere una pagina completamente responsive

A prescindere dal fullscreen, che teoricamente (anche in base ai vari test effettuati) dovrebbe funzionare su tutti i dispositivi, è opportuno sfruttare tutto lo spazio a disposizione. Non sempre l’utente finale usa un tablet, anzi nella maggior parte dei casi avremo a che fare con smartphone medio/piccoli, per cui abbiamo bisogno di tutto lo spazio disponibile. Adobe Animate offre alcune opzioni per rendere la nostra pagina HTML5 responsive. Tuttavia, dopo averle provate in modalità fullscreen, non sono rimasto soddisfatto del risultato finale. In alcuni dispositivi android e mac, per rispettare le proporzioni tra larghezza e altezza, vengono generate delle piccole zone vuote lungo i lati (a volte in orizzontale a volta in verticale). A mio parere, se vogliamo a sfruttare al massimo lo spazio abbiamo bisogno di non andare troppo per il sottile e forzare il browser a darci tutta l’area disponibile. Inoltre, soprattutto quando parliamo di smartphone, la distorsione delle immagini derivata da una modalità responsive integrale è abbastanza irrisoria, per cui il gioco vale la candela.
Stavo pensando di implementare una soluzione ad hoc quando sono incappato in un tutorial di Joseph Labrecque, se non lo conoscete vi consiglio di mettere il suo blog nei preferiti. Per cui ecco di seguito il primo blocco di codice presente nel fotogramma azioni:

createjs.Ticker.timingMode = createjs.Ticker.RAF_SYNCHED;
createjs.Touch.enable(stage);
// ---------------------------------------------------------
// soluzione responsive di Joseph Labrecque 
// ---------------------------------------------------------
var page_body = document.getElementsByTagName("body")[0];
page_body.style.backgroundColor = "#cccccc";
page_body.style.overflow = "hidden";
page_body.style.position = "fixed";
var page_canvas = document.getElementsByTagName("canvas")[0];
stageWidth = page_canvas.width;
stageHeight = page_canvas.height;
var viewport = document.querySelector('meta[name=viewport]');
var viewportContent = 'width=device-width, initial-scale=1.0, 
minimum-scale=1.0, maximum-scale=1.0, user-scalable=0';
if (viewport === null) {
 var head = document.getElementsByTagName('head')[0];
 viewport = document.createElement('meta');
 viewport.setAttribute('name', 'viewport');
 head.appendChild(viewport);
}
viewport.setAttribute('content', viewportContent);
function onResize() {
 var newWidth = window.innerWidth;
 var newHeight = window.innerHeight;
 page_canvas.style.height = newHeight + "px";
 page_canvas.style.width = newWidth + "px";
 stage.width = newWidth;
 stage.height = newHeight;
}
window.onresize = function () {
 onResize();
}
onResize();

Tralasciando le prime 2 righe – di cui abbiamo parlato negli articoli precedenti – la soluzione di Labrecque prevede una funzione che al verificarsi dell’evento onresize costringe lo stage ad assumere le dimensioni delle variabili innerWidth e innerHeight. In teoria, se il browser dovesse non accettare l’innesco della modalità fullscreen, avremo comunque  usato al massimo lo spazio disponibile.

Rilevare l’orientamento dello schermo

Quando si realizza un gioco per i dispositivi mobili è molto importante stabilire come l’utente deciderà di interagire. Se realizziamo uno gioco in cui l’orientamento non è importante, il problema non si pone, ma se (come nel puzzle che realizzeremo) abbiamo un verso predefinito ci sono solo due possibilità: rendere il gioco fruibile a prescindere dalla rotazione del dispositivo affidandoci alla discrezionalità dell’utente, oppure imporre il modo in cui bisognerà orientare il dispositivo per giocare.
Purtroppo l’utente medio (e parlo di me in primis) va sempre di fretta, è distratto, impaziente e con pochissima voglia di leggere eventuali istruzioni. Quindi per evitare che il giocatore avvi il puzzle nel verso sbagliato e chiuda l’applicazione pensando che non funzioni correttamente, ci conviene creare dei percorsi obbligatori. Un trucco è quello di nascondere il gioco e contemporaneamente mostrare un messaggio informativo tutte le volte che l’utente ruota il dispositivo nel verso sbagliato.

full_fig2

Nel mio caso ho posizionato un clip filmato chiamato msg in un livello che copre tutti gli elementi grafici. Il clip è caratterizzato da un quadrato bianco largo quanto lo stage al quale sono sovrapposti un disegno indicativo e una breve frase. Ecco di seguito il blocco di codice che verifica e suggerisce il corretto orientamento.

// ---------------------------------------------------------
// controllo orientamento schermo 
// ---------------------------------------------------------
// verifica iniziale
function controlloIniziale(){
if(window.innerHeight > window.innerWidth){
exportRoot.msg.visible=true;
exportRoot.p_start.visible=exportRoot.p_off.visible=false;
}
else if(window.innerHeight < window.innerWidth){
exportRoot.msg.visible=false;
exportRoot.p_start.visible=exportRoot.p_off.visible=true;
}
}
// verifica alla rotazione
function controllo(){
if(window.orientation==0 || window.orientation==180){
exportRoot.msg.visible=true;
exportRoot.p_start.visible=exportRoot.p_off.visible=false;
}
else {
exportRoot.msg.visible=false;
exportRoot.p_start.visible=exportRoot.p_off.visible=true;
}
}
controlloIniziale();

Il codice è caratterizzato da due funzioni controlloIniziale() e controllo(). Si tratta di due approcci diversi per svolgere lo stesso compito. La prima funzione (molto intuitiva) verifica le dimensioni dello stage con un’istruzione condizionale: se l’altezza è maggiore della larghezza appare il messaggio, viceversa scompare. Inoltre, quando appare il messaggio vengono resi invisibili – e quindi non cliccabili, i due pulsanti di regolazione p_start e p_off.
Purtroppo il metodo controlloIniziale(), efficace al primo caricamento della pagina, non ci consente di catturare la rotazione del dispositivo effettuata dall’utente e questo ci porta alla necessità di ricorrere ad una seconda funzione.
La funzione controllo() prevede delle istruzioni condizionali che verificano il valore della proprietà orientation dell’oggetto window. Questa proprietà ogni volta che ruotiamo il nostro smartphone cambia il suo valore e precisamente:

  • se posizioniamo il dispositivo con la parte alta rivolta a destra otteniamo -90;
  • se lo capovolgiamo (con la telecamera rivolta verso il basso) 180;
  • se lo posizioniamo con la parte alta rivolta a sinistra 90;
  • se riportiamo il dispositivo nella sua posizione normale (verticale, con l’occhio della telecamera rivolta verso l’alto) 0.

schemasm

Ovviamente le istruzioni condizionali del nostro esempio sono pensate per far apparire il disclaimer solo se l’utente non posiziona lo smartphone in orizzontale. Ma volendo ragionare al contrario, ovvero nel caso in cui abbiamo un gioco pensato per essere giocato solo in verticale, dovremmo solo cambiare il codice come segue:

if(window.orientation==90 || window.orientation==-90){
exportRoot.msg.visible=true;
exportRoot.p_start.visible=exportRoot.p_off.visible=false;
}
else {
exportRoot.msg.visible=false;
exportRoot.p_start.visible=exportRoot.p_off.visible=true;
}

Infine, per intercettare i valori delle proprietà orientation è necessario associale la funzione controllo() all’evento orientationchange. Per una questione di comodità ho inserito il codice relativo nella parte finale del listato assieme agli altri gestori di evento.

Impostare il fullscreen

Un altro aspetto fondamentale da prendere in considerazione quando si sviluppa per i dispositivi mobili è la possibilità di attivare la modalità a schermo pieno: in questo modo possiamo conquistare spazio ulteriore sottraendolo alle barre del browser.
Dopo essermi documentato ho scovato una soluzione che sembra girare egregiamente su tutti i browser di ultima generazione. Inoltre, come ho già scritto all’inizio dell’articolo, nel caso di browser obsoleti che negano la possibilità di sfruttare lo schermo pieno, abbiamo comunque il codice che rende lo schermo responsive pronto a toglierci le castagne dal fuoco.
Poiché il fullscreen richiede sempre l’attivazione tramite un pulsante, ci conviene approfittarne per far partire il gioco con un pulsante di avvio. Ecco di seguito il codice che gestisce la modalità a schermo pieno:

// ---------------------------------------------------------
// fullscreen
// ---------------------------------------------------------
function attivaFullscreen() {
 if(document.documentElement.requestFullscreen) {
 document.documentElement.requestFullscreen();
 } else if(document.documentElement.mozRequestFullScreen) {
 document.documentElement.mozRequestFullScreen();
 } else if(document.documentElement.webkitRequestFullscreen) {
 document.documentElement.webkitRequestFullscreen();
 } else if(document.documentElement.msRequestFullscreen) {
 document.documentElement.msRequestFullscreen();
 }
this.p_start.x-=1000;
animazione();
}
// fullscreen off
function disattivaFullscreen() {
 if(document.exitFullscreen) {
 document.exitFullscreen(); 
 } else if(document.mozCancelFullScreen) {
 document.mozCancelFullScreen(); 
 } else if(document.webkitExitFullscreen) {
 document.webkitExitFullscreen(); 
 }else if (document.msExitFullscreen) {
 document.msExitFullscreen();
 }
}

Come è possibile osservare abbiamo due funzioni, una che avvia il fullscreen attraverso il pulsante p_start e una che lo disattiva tramite il pulsante p_off. Nel primo caso mettiamo in atto quella che nel gergo viene definita tecnica di sniffing, in altre parole vengono individuate una serie di variabili booleane utili per identificare varie tipologie di browser, poi in base al risultato si attiva un’istruzione che innesca il fullscreen solo per quello specifico caso. Ad esempio, facendo qualche test sul campo è possibile notare che il metodo webkitExitFullscreen() attiva il fullscreen per Chrome, Edge ed Opera, mozRequestFullScreen() per Firefox e msRequestFullscreen() per le vecchie versioni di Explorer. La funzione svolge anche altri due compiti: innesca l’animazione del logo e sposta il pulsante di avvio in una zona lontana dall’area cliccabile mettendolo fuori gioco.
Discorso analogo per i metodi di uscita usati nella funzione di uscita: anche in quel caso si identifica prima il browser e poi si associa il metodo corretto per disabilitare il fullscreen.

Gli ultimi ritocchi  

Per rendere il discorso più scorrevole ho suddiviso le varie parti del codice in base agli argomenti senza rispettare le convenzioni: ad esempio per essere più ordinato avrei dovuto dichiarare tutte le variabili all’inizio del codice. In ogni caso ecco l’ultimo blocco del listato:

// ---------------------------------------------------------
// animazione
// ---------------------------------------------------------
var target = this.clip1;
var animazione = function () {
 exportRoot.clip1.gotoAndPlay(1);
}
// ---------------------------------------------------------
// eventi
// ---------------------------------------------------------
this.msg.scaleX = 3.2;
this.p_start.on("click", attivaFullscreen.bind(this));
this.p_off.on("click", disattivaFullscreen.bind(this));
window.addEventListener("orientationchange", controllo.bind(this), false);

Nella prima parte ci sono le istruzioni che attivano l’animazione quando si preme il pulsante p_start, a seguire abbiamo un aggiustamento della dimensione orizzontale del clip msg per compensare la distorsione che deriva dalla rotazione verticale in modalità responsive. Infine nelle ultime tre righe possiamo osservare tre eventi ai quale sono associati tre funzioni listener. In particolare l’ultimo evento cattura la rotazione del dispositivo mobile tramite l’evento orientationchange.
Per concludere, quando pubblichiamo tramite l’apposito pannello, dobbiamo ricordarci di non selezionare l’opzione Rendi reattivo: poiché abbiamo già scritto manualmente le istruzioni necessarie alla visualizzazione responsive, attivare anche le impostazioni fornite dal programma servirebbe solo a scompaginare il tutto. Selezioniamo quindi solo Centra allo stage e Incorpora precaricatore.

full_pubA proposito del precaricatore c’è un ultimo passo da compiere. Siccome il codice per centrare il documento è ridondante rispetto al codice JavaScript bisogna aprire il file HTML5 con un editor e cancellare il selettore #canvas nel rigo: #canvas, #_preload_div_ {

<style>
 #_preload_div_ {
 position:absolute;
 margin:auto;
 left:0;right:0;
 top:0;bottom:0;
 }
</style>

Questa correzione ala CSS ci consentirà di posizionare la gif usata come precaricamento al centro della pagina web. Per finire, è importante notare che questo meccanismo si presta anche alla creazione di “siti spot” a schermo pieno dal forte impatto visivo. Chiaramente ci sarebbero alcuni accorgimenti ulteriori da seguire, ma non è affatto difficile. Per ora è tutto. Come sempre, ecco il  link per scaricare il sorgente dell’esempio:

Scarica i file sorgenti

 

Share:

Leave a reply

*