Gestire gli eventi in CreateJS (prima parte)

0
Share:

Nel post precedente abbiamo analizzato la struttura generale di un progetto multimediale realizzato con HTML5 e createJS. Come abbiamo visto, gli approcci più gettonati dai developer sono due: scrivere tutto manualmente oppure usare Adobe Animate CC. Del resto, vista la partnership tra Adobe e Gskinner, se si rinuncia all’approccio manuale, Animate risulta indubbiamente uno strumento estremamente efficace per velocizzare il processo produttivo.
Programmare in createJS tramite l’applicativo comporta numerose comodità. Prima di tutto, poiché ci penserà il programma la posto nostro, non dobbiamo progettare la struttura iniziale del file HTML5, nel quale molte istruzioni di base – come quelle legate alla definizione dell’area di lavoro  – vengono settate visualmente e pubblicate in automatico. In secondo luogo, grazie al pannello Snippet, abbiamo a disposizione un nutrito archivio di script pronti da cui partire. In terzo luogo, il pannello Azioni (tramite il quale scriviamo il codice) ci offre dei piccoli suggerimenti strada facendo. E per finire, abbiamo a disposizione un potente programma grafico tramite il quale disegnare/importare/modificare tutto quello di cui abbiamo bisogno. Insomma, una serie di scorciatoie che ci consentono di concentrarci sulla scrittura di createJS senza sprecare tempo prezioso. 
A proposito di createJS, bisogna sottolineare le sostanziali differenze che caratterizzano questo linguaggio rispetto all’altro strumento di programmazione previsto in Adobe Animate. Mentre lo storico ActionScript 3 ha alle sue spalle circa quindici anni di storia ed è a tutti gli effetti un linguaggio OOP solido che ha molto in comune con i più blasonati linguaggi C oriented, createJS è un po’ meno potente, ma molto più agile.
Quando programmiamo nel linguaggio ideato da Grant Skinner non è necessario tipizzare i dati o le funzioni, possiamo inserire tutto il codice nei fotogrammi senza dover creare delle classi, e più in generale, abbiamo un approccio molto intuitivo. Restano le normai regole previste in JavaScript, come ad esempio il rispetto della aree di validità delle variabili, la sintassi del punto e le istruzioni più comuni presenti nel celebre linguaggio di scripting.
Nonostante qualche limite, CreateJS risulta uno strumento impressionante per le cose che è in grado di fare. Inoltre non dimentichiamo che è un linguaggio “giovane” ben lontano dall’esprimere tutto il suo potenziale. Utilizzandolo in Adobe Animate, possiamo con poche righe avere il pieno controllo delle istanze di oggetti, ovvero la categorie di elementi visivi (importate o disegnate) ai quali è possibile dare un nome di istanza: pulsanti, campi di testo e clip filmati.
Ci sarebbero tante altre cose da dire sull’argomento, ma non voglio dare a questo articolo un taglio troppo teorico, per cui dopo tante chiacchiere è arrivato il momento di passare alla pratica.

Rilevare la presenza del mouse sullo stage

Allo stesso modo delle applicazioni AIR, l’area di lavoro fa riferimento alla classe stage, le cui proprietà ci consentono di monitorare vari aspetti del nostro progetto tramite codice. Ad esempio, per leggere la larghezza totale possiamo ricorrere all’espressione: stage.canvas.width mentre per leggere l’altezza totale stage.canvas.height.
Supponiamo di voler sapere quando e se l’utente posizione il mouse al di fuori dello stage (la tipica situazione che ci potrebbe interessare nel caso in cui stessimo realizzando un webgame). L’esempio completo lo trovate qui.
Per evitare di ricorrere ai soliti alert o console.log di JavaScript, ho usato un campo di testo creato dinamicamente. Nel campo in questione appare un scritta che comunica l’assenza o la presenza del mouse. Di seguito ripercorriamo i passi necessari per realizzare l’esempio.
Dopo aver aperto un nuovo progetto HTML5 canvas, selezioniamo il primo fotogramma e scriviamo il seguente codice:

var campo1 = new createjs.Text();
campo1.color = "#003366";
campo1.font = "18px Arial";
campo1.textAlign = "leftt";
campo1.lineWidth = 200;
campo1.lineHeight = 22;
campo1.x = 175;
campo1.y = 189; 
campo1.text = "Animate"; 
this.addChild(campo1);

Nella prima riga di codice creiamo un’istanza della classe Text denominata campo1. Analogamente a quanto avviene per altri linguaggi, il testo viene creato dinamicamente tramite codice. Una sequenza di istruzioni caratterizzate da varie coppie nome=valore, regolano tutti gli aspetti del campo di testo. Si tratta di proprietà molto intuitive che non necessitano di spiegazioni particolari: colore, font, allineamento, larghezza, altezza, ascissa e ordinata. Nella penultima istruzione viene stabilita la scritta che apparirà nel campo tramite la proprietà text. Infine, l’ultima istruzione posiziona dinamicamente il campo sullo stage. La documentazione ufficiale sul sito di createJS, di solito disegna dinamicamente un oggetto shape per colorare l’area nel quale apparirà il testo. Poiché questa soluzione è equivalente all’utilizzo di un disegno realizzato in modo visuale, invece di affollare inutilmente il codice, creiamo un rettangolo bianco 200 pixel per 22 e diamogli le stesse coordinate del testo. Eventualmente, se vogliamo che ci sia un leggero margine tra la prima lettera e il bordo, possiamo spostarlo a sinistra di un paio di pixel con le freccia della tastiera.

stage1

A questo punto tutto è pronto per rilevare la posizione del mouse. Selezioniamo il fotogramma nel quale abbiamo inserito la prima parte del codice e aggiungiamo le seguenti righe:

// gestione eventi sullo stage
stage.mouseMoveOutside = true;
stage.addEventListener("stagemousemove", function(evt) { 
 if(evt.rawX>stage.canvas.width || evt.rawX<0){campo1.text = "fuori"}
 else if (evt.rawY>stage.canvas.height || evt.rawY<0){campo1.text = "fuori"} 
 else {campo1.text = "dentro"}
});

Qui il discorso diventa leggermente più complicato. Prima di tutto abbiamo settato su true la proprietà mouseMoveOutside che abilita il “monitoraggio” del mouse al di fuori dello stage. Nella riga successiva entra in gioco stagemousemove, un evento specializzato nel rilevare i movimenti del mouse sullo stage.  Come si può osservare, abbiamo usato una funzione listener generica direttamente nell’istruzione addEventListener. Il corpo di questa funzione è caratterizzata da un if, un else if, e un else.
Nella prima istruzione condizionale si stabilisce uno dei due casi in cui dovrà a apparire la scritta “fuori” nel campo di testo: ovvero quando il valore di evt.rawX è maggiore della larghezza dello stage oppure quando è minore di zero. L’espressione evt.rawX restituisce la posizione del mouse nel browser. In particolare la proprietà rawX (simile a stageX), viene usata quando mouseMoveOutside è impostata su true, e consente di calcolare in modo accurato la posizione del cursore sull’asse x.
Discorso analogo per l’istruzione else if: in quel caso, grazie alla proprietà rawY,  viene rilevato quando il mouse si trova oltre  margini verticali dello stage.
Infine l’istruzione else verifica tutti gli altri casi, ovvero quando il cursore si trova nei margini dello stage. Di seguito il link per scaricare il file sorgente:

Scarica il file.

Gli eventi principali 

Ma se nel caso dello stage abbiamo a che fare con eventi e proprietà specifici, per le istanze entrano in gioco dei gestori simili a quelli previsti in tantissimi altri ambienti di sviluppo. Per testare gli eventi principali di createJS, mi sono divertito a realizzare un piccolo esempio che trovate qui.
In pratica, sono stati creati 4 pulsanti che innescano quattro funzioni listener legate ad altrettanti eventi. Tutti i pulsanti, una volta premuti, modificano dinamicamente il valore di un campo di testo creato dinamicamente.
Volendo far il punto della situazione, i principali  gestori di evento sono i seguenti (gli altri li vedremo strada facendo nei prossimi post) :

  • click: rileva la pressione generica del pulsante del mouse senza distinguere da pressione e rilascio;
  • mousedown: rileva la pressione del mouse;
  • pressup: rileva il rilascio del pulsante del mouse;
  • mouseover e rollover : rileva quando il mouse passa sopra un oggetto specifico.
  • mouseout e rollout: rileva quando il mouse si sposta al d fuori dell’area di un oggetto specifico.
  • tick: rileva l’aggiornamento delle frequenza dei fotogrammi. Molto simile all’evento EnterFrame è utile per attivare delle funzioni ricorsive.

Nel piccolo elenco è possibile notare la similitudine tra mouseover e rollover. In realtà, anche se sembrano svolgere lo stesso compito, esiste una sfumatura che li distingue. Mentre mouseover analizza la posizione del mouse a prescindere dalla presenza di eventuali altri oggetti parzialmente sovrapposti, il secondo è più rigido nell’analizzare l’area di riferimento: nel caso di aree condivise, l’evento rollover legge solo ed esclusivamente l’area legata all’oggetto al quale è associato. Di seguito ripercorriamo i passi per la creazione del secondo esempio a partire dalla parte grafica.mouse1cCome si può osservare nella figura in alto, il file è caratterizzato da cinque livelli. Nel primo livello denominato rotella, dobbiamo collocare un oggetto da ruotare tramite il pulsante ATTIVA TICK. Va bene un disegno qualsiasi (un rettangolo, un poligono, ecc.), nel mio caso mi sono divertito a disegnare un’ingranaggio usando gli strumenti di disegno del programma.
Una volta posizionato l’oggetto convertiamolo in clip filmato e diamogli come nome istanza rotella. Come è possibile notare, il clip è in parte fuori dallo stage, così facendo, durante la rotazione vedremo solo un parte dell’oggetto in movimento. Analogamente a quanto avviene con le applicazioni AIR, dopo la pubblicazione di una pagina HTML5, sono visualizzati solo gli elementi che si trovano sullo stage.
Nel secondo livello – denominato cornice – è possibile collocare degli elementi visivi che copriranno parzialmente la rotella durante la rotazione in modo da accentuare la resa scenica. Nel mio esempio ho inserito una cornice e il dominio del blog.
Nel terzo livello posizioniamo quattro pulsati i cui nomi di istanza sono, a partire dall’alto verso il basso: p1, p2, p3 e p4. Anche in questo caso mi sono divertito a crearli con gli strumenti di disegno, ma vanno bene anche quattro rettangoli semplici.
Nel livello area campo, analogamente a quanto visto per l’esempio precedente, dobbiamo posizionare un rettangolo 200 pixel per 22 alle coordinate x=173 e y=189. tale rettangolo farà da sfondo al campo creato dinamicamente.

Infine nel livello azioni, scriviamo il seguente codice:

// creazione campo
var campo1 = new createjs.Text();
campo1.color = "#003366";
campo1.font = "18px Arial";
campo1.textAlign = "leftt";
campo1.lineWidth = 200;
campo1.lineHeight = 22;
campo1.x = 175;
campo1.y = 189;
campo1.text = "";
this.addChild(campo1);
// clic
this.p1.addEventListener("click", evt_click.bind(this));
function evt_click()
{
campo1.text = "clic utente";
}
// rollover
this.p2.addEventListener("rollover", evt_over);
function evt_over()
{
campo1.text = "rollover utente";
}
// rollout
this.p2.addEventListener("rollout", evt_out);
function evt_out()
{ 
 campo1.text = "rollout utente";
}
// doppio clic
this.p3.addEventListener("dblclick", evt_dbc);
function evt_dbc()
{ 
 campo1.text = "doppio clic";
}
// evento tick
this.p4.addEventListener("click", accendi.bind(this));
function accendi(){
this.addEventListener("tick", ruota.bind(this));
campo1.text = "rotazione";
}
function ruota(){
 this.rotella.rotation+=1;
}

La prima parte del listato è identica a quella del primo esempio. Anche in questo caso creiamo un campo di testo, ne definiamo le caratteristiche e lo collochiamo sullo stage. L’unica differenza è il valore della proprietà text, alla quale questa volta passiamo una stringa vuota.
A seguire ci sono una serie di listener associati ai vari pulsati. La sintassi dei primi tre (davvero semplicissima), ha una struttura di questo tipo:

this.nomepulsante.addEventListener(“evento”, nomefunzione.bind(this));
nomefunzione (){
campo1.text=”risultato”;
}

Dove nomefunzione è la funzione listener che ha il compito di cambiare la scritta quando si verifica l’evento. Volendo risparmiare tempo è anche possibile scrivere le istruzioni con il pannello pannello Snippet di codice e poi modificarle in base alle proprie esigenze.
La quarta è ultima istruzione del listato è stata ricavata proprio modificando il codice che si ottiene dalla seguente opzione prevista nel pannello Snippet di codice:

HTML5 canvas > Animazione > Ruota continuamente.

Osservano il codice finale abbiamo un pulsante p4 che se premuto attiva l’evento tick. Tale evento ha una funzione listener denominata ruota(), il cui compito è quello di incrementare la proprietà rotation del clip filmato rotella.
L’evento tick, analogamente all’evento EnterFrame che si usa nelle applicazioni AIR, ripete delle istruzioni in modo ricorsivo con una velocità legata al valore FPS del programma. Più è alta la frequenza dei fotogrammi per secondo – che si imposta nel pannello Proprietà, più velocemente sarà ripetuta la funzione listener associata. Lasciando come valore di default una frequenza pari a 24, basta incrementare la proprietà rotation di un solo grado per ottenere una rotazione adatta alle nostre esigenze.
In teoria l’esempio sarebbe ultimato, ma questo codice ha due difetti. Prima di tutto non prevede il tasto per bloccare la rotazione (anticipo che in createJS non è previsto removeEventListener così come è usato in AS3).  In secondo luogo, consente l’aumento involontario della velocità del clip rotella: infatti premendo ripetutamente il pulsante, viene incrementata la rotazione dell’istanza. Si tratta di piccoli ritocchi che effettueremo nel prossimo post. Ecco  il link per scaricare il sorgente dell’esempio:

Scarica il file.

Share:

Leave a reply

*