La classe Tween in createJS

2
Share:

La classe Tween, una tra le più importanti di createJS, ci consente di animare tutti gli elementi visivi dei nostri progetti tramite poche righe di codice. Poiché questa guida introduttiva a createJS ha come ambiente di riferimento Adobe Animate, ci si potrebbe legittimamente chiedere per quale motivo non accontentarsi delle numerose funzioni multimediali offerte dal tool. La risposta è semplicissima: le animazioni che è possibile creare “manualmente” – per quanto comode ed efficaci – non possono soddisfare tutte le possibili esigenze progettuali. Ci sarà sempre una situazione nella quale, per raggiungere un dato scopo, bisognerà ricorrere alla programmazione.
Una buona conoscenza della classe Tween ci consente di impostare banner accattivanti, siti web complessi di grande impatto visivo, e suggestivi instant game in HTML5. Purtroppo la sintassi di questa classe è abbastanza caotica: una sola istruzione caratterizzata da numerosi parametri e metodi, tutti inscatolati l’uno nell’altro in un frullato di righe. Un aspetto che a prima vista potrebbe scoraggiare chi non è molto allenato con la programmazione. Ma niente paura, come vedremo nel corso di questo articolo, dietro quel disordine visivo si nasconde un codice semplicissimo.
Un modo per iniziare a prendere al mano con la classe Tween, è usare il codice presente nel pannello Snippet. Per creare un primo esempio al volo ci vuole meno di un minuto.
In base al tipo di approccio che ho deciso di seguire nella stesura di questa mini guida su createJS, seguirò tutti i passaggi visuali, presumendo che non tutti i lettori conoscono a sufficienza l’interfaccia di Adobe Animate. Piccolo inciso, io uso l’interfaccia classica. Si imposta da Finestra > Aree di lavoro > Classica.

  1. Apriamo un nuovo documento HTML5 Canvas da File Nuovo > HTML5 Canvas.
  2. Collochiamo sullo stage un clip filmato. Nel mio caso ho usato il logo di Adobe Animate, ma va bene anche un disegno semplice. Ad esempio potremmo disegnare un quadrato e poi convertirlo in clip filmato. Come si fa? Semplicissimo: disegniamo un quadrato con lo strumento Rettangolo e poi apriamo il pannello per la conversione da Elabora > Converti in simbolo. Scegliamo nel menu a tendina clip filmato e premiamo Ok.
  3. Senza deselezionarlo, nel pannello Proprietà diamogli come nome di istanza an. Posizioniamolo in alto a sinistra e lasciamolo selezionato.
  4. Apriamo il pannello degli esempi da Finestra >  Snippet di codice,
  5. Selezioniamo l’opzione HTML5 Canvas > API di createJS > Interpolazione utilizzando codice.
  6. Pubblichiamo il file HTML5 da File > Impostazioni di pubblicazioni > Pubblica.

A questo punto, otterremo un effetto di questo tipo.
In pratica l’oggetto si muove, ruota e cambia direzione. Se osserviamo la linea temporale del file, noteremo un fotogramma Actions creato dal programma con le istruzioni che controllano l’animazione.

var target = this.an;
var tween = createjs.Tween.get(target, {
 loop: true
})
 .to({
 x: target.x,
 y: canvas.height - 55,
 rotation: -360
 }, 1500, createjs.Ease.bounceOut)
 .wait(1000)
 .to({
 x: canvas.width - 55,
 rotation: 360
 }, 2500, createjs.Ease.bounceOut)
 .wait(1000)
 .to({
 scaleX: 2,
 scaleY: 2,
 x: canvas.width - 110,
 y: canvas.height - 110
 }, 2500, createjs.Ease.bounceOut);

Il listato è stato pensato per dare un assaggio di tutte le più importanti funzionalità che caratterizzano la classe Tween. Purtroppo, come ho anticipato prima, chi non ha l’occhio allenato potrebbe vedere il codice come un frullato di istruzioni abbastanza confuso. Di seguito vivisezioniamolo un pezzo alla volta:

var target=this.an;
var tween = createjs.Tween.get(target, {
 loop: true
})

Nella prima istruzione abbiamo una variabile denominata target il cui compito è quello di memorizzare il nome del clip che andremo ad animare. Si tratta di una scorciatoia non obbligatoria adottata dal programma per non riscrivere il percorso completo del clip tutte le volte (se al posto di target scrivessimo direttamente this.an, l’animazione funzionerebbe lo stesso).
La variabile tween crea in modo implicito un’istanza della classe. L’istruzione che gli viene passata attraverso l’operatore di assegnazione, mette automaticamente in moto l’animazione .
L’istruzione get stabilisce alcune caratteristiche della nostra animazione: che ad essere animato è il clip a cui si riferisce la variabile target e che la proprietà loop sarà fissata su true creando una ripetizione continua dell’effetto visivo.
Passiamo al blocco successivo:

 .to({
 x: target.x,
 y: canvas.height - 55,
 rotation: -360
 }, 1500, createjs.Ease.bounceOut)

Il metodo to costituisce il cuore del nostro codice, grazie ai suoi parametri vengono stabiliti i valori da modificare dinamicamente per creare l’effetto movimento. Nel listato riportato in alto vengono modificate le coordinate e la rotazione del clip.
Per la precisione, specificando target.x come valore dell’ascissa stabiliamo che il clip filmato manterrà la propria posizione sull’asse delle x muovendosi solo in verticale.
L’espressione canvas.height-55 stabilisce che l’oggetto scorrerà verso il basso e si fermerà 55 pixel prima del bordo inferiore. Attribuendo alla proprietà rotation il valore -360, stabiliamo una rotazione in senso antiorario durante lo spostamento. Infine, il valore 1500 indica i millisecondi necessari per effettuare il movimento e createjs.Ease.bounceOut il tipo di andamento.
A questo riguardo facciamo un piccolo inciso. Analogamente a quanto previsto in altri linguaggi di programmazione, quando usiamo la classe dedicata al movimento è possibile stabilire il tipo di andatura. Ad esempio bounceOut imposta un effetto rimbalzo alla fine del movimento, regular un andamento costante e elasticOut un effetto elastico alla fine del movimento.
Molti effetti possono essere in entrata (e in quel caso hanno la parola che termina con le lettere “In”) oppure in uscita (con la parola che che termina in “Out”). Sul sito ufficiale sono elencati tutti i tipi di andamento. Sono tantissimi e c’è solo l’imbarazzo della scelta.
Riprendiamo l’analisi del listato con la porzione di codice successiva:

.wait(1000)
 .to({
 x: canvas.width - 55,
 rotation: 360
 }, 2500, createjs.Ease.bounceOut)

Il metodo wait specifica in millisecondi il tempo di attesa prima di compiere altri movimenti. Nel nostro caso, dopo essersi spostato verso il basso, il nostro clip avrà una pausa di un secondo. A seguire abbiamo una seconda istruzione to che sposterà l’oggetto a meno di 55 pixel dal bordo destro ed effettuerà una rotazione oraria. La durata dell’animazione sarà di due secondi e mezzo. A questo punto non ci resta che analizzare l’ultima parte del codice:

.wait(1000)
 .to({
 scaleX: 2,
 scaleY: 2,
 x: canvas.width - 110,
 y: canvas.height - 110
 }, 2500, createjs.Ease.bounceOut);

Abbiamo un’ulteriore pausa di un secondo e poi un ultima istruzione to. Questa volta a cambiare sono le proprietà scaleX, scaleY, x ed y. Le prime due regolano la dimensioni del clip in percentuale, passandogli come valore 2, ingrandiremo il clip del 200 %. Le coordinate x ed y sono invece impostate per posizionare l’istanza nell’angolo inferiore destro: 110 pixel prima del bordo destro e 110 pixel prima del limite inferiore. E con quest’ultima porzione di codice abbiamo commentato tutto il listato. Volendolo schematizzare il codice appena analizzato, possiamo dire che è contraddistinto da tre fasi:

  • la creazione dell’istanza della classe con il riferimento al nome dell’oggetto da muovere,
  • l’utilizzo del metodo get per specificare le caratteristiche principali dell’animazione,
  • una sequenza di metodi per muovere e mettere in pausa l’oggetto.

Prima di proseguire il discorso, una semplice considerazione: difficilmente in un progetto reale useremmo l’approccio visto nell’esempio, con il clip che si muove da solo rotolando a destra e sinistra più volte. Al massimo ci potrebbe servire se usassimo la classe in questione per realizzare un banner animato, ma anche in quel caso ci basterebbero gli strumenti del tool.
Il più delle volte le animazioni via codice sono associate all’interattività, situazioni in cui l’utente finale (visitatore di un sito web dinamico o giocatore di un game HTML5) fa qualcosa per innescare un Tween.
A questo riguardo, il codice appena illustrato può essere riscritto in modo molto più flessibile. Ad esempio, possiamo collocare il metodo get in una funzione da chiamare al verificarsi di un evento, definire le proprietà da cambiare in modo dinamico, spezzettare il codice in porzioni più comode da maneggiare e così via.

Animazioni innescate dal clic del mouse

Facciamo un piccolo esempio basato sulle interazioni con l’utente. Supponiamo di voler realizzare una pagina HTML5 dove ad ogni clic del mouse un oggetto si sposta in quel preciso punto. Per rendere più carino l’effetto, facciamo in modo che lo sfondo cambi colore casualmente quando l’animazione si conclude. L’esempio finito lo trovate QUI. Di seguito ripercorriamo i passi necessari per la sua realizzazione.

  1. Apriamo un nuovo documento HTML5 canvas e regoliamo la dimensione dello stage nel pannello Proprietà. Nel mio esempio uso un’area di lavoro 620 per 400, ma non sono valori vincolanti.
  2. Disegniamo un rettangolo di un colore qualsiasi con lo strumento Rettangolo.
  3. Selezioniamolo e tramite il pannello Informazioni che si apre da Finestra > Informazioni, diamogli le stesse dimensioni dello stage. infoA
  4. Tenendolo selezionato, apriamo il pannello apposito da  Elabora > Converti in simbolo. Diamogli come nome base e scegliamo dal menu a tendina: Clip Filmato. Inoltre, se non è già impostato di default, diamogli come punto di registrazione quello in alto a sinistra. Infine premiamo su OK.conva2
  5. Sempre tendendo selezionato il clip, nel pannello Proprietà diamogli come nome istanza base. Questo simbolo sarà lo sfondo che cambia casualmente colore ogni volta che termina un effetto Tween.
  6. Facciamo doppio clic sul simbolo, in modo da accedere alla sua libreria interna, Dopo aver selezionato il primo fotogramma premiamo Canc sulla nostra tastiera in modo da eliminare il rettangolo. Clicchiamo su Scena 1 per tornare al livello principale: noteremo un cerchietto vuoto. Cosa è accaduto? Semplicemente, in createJS funzionano molti dei trucchetti che Animate ha ereditato dal suo genitore. I passaggi elencati ci hanno consentito di creare un clip filmato vuoto, ovvero una sorta di clip invisibile da riempire e manipolare tramite codice. Qualcosa di simile si può ottenere anche programmando, ma l’approccio visivo ci consente di  spostarlo manualmente dove vogliamo. Useremo questo simbolo per disegnare al suo interno un rettangolo che cambia colore in modo casuale.clip_vuoto1
  7. Facciamo doppio clic sul livello in cui si trova il simbolo e denominiamolo rettangolo.
  8. Creiamo un  nuovo livello da Inserisci > Linea Temporale > Livello. Scriviamo con lo strumento testo una frase che spiega come funzione l’esempio, qualcosa del tipo: “clicca in un punto qualsiasi”. Rinominiamo il livello appena creato come sfondo.
  9. Creiamo un nuovo livello e chiamiamolo clip. Collochiamo nel primo fotogramma l’oggetto che vogliamo muovere. Nel mio caso ho usato il logo di Adobe Animate, ma come abbiamo visto nell’esempio precedente, va bene anche un disegno semplice. La cosa è importante è non dimenticare di dargli come nome di istanza an nel pannello Proprietà. livelli_an
  10. Aggiungiamo un nuovo livello e rinominiamolo azioni. Nel primo fotogramma scriviamo il seguente codice.
var target = this.an;
stage.on("stagemousedown", function (e) {
var px=e.stageX;
var py=e.stageY;
var tween = createjs.Tween.get(target, {
 loop: false
})
 .to({
 x: px,
 y: py,
 }, 500, createjs.Ease.regular)
});
// crea il rettangolo
var shape = new createjs.Shape();
var coloreCmd = shape.graphics.beginFill("#006699").command;
var rettangoloCmd = shape.graphics.drawRect(0,0,620,400).command; 
this.base.addChild(shape);

Come si può notare osservando il listato, abbiamo modificato leggermente il codice visto nell’esempio precedente. Il blocco di codice che ha il compito di animare l’oggetto an, è collocato all’interno di una funzione listener generica, attivata a sua volta da un evento stagemousedown. Ogni volta che l’utente clicca in un punto dello stage, vengono definite coordinate px e py di destinazione. Questa volta la proprietà loop è settata su false (quindi l’animazione non viene ripetuta) e l’andamento è regular (ovvero costante). Il secondo blocco di codice si limita a creare dinamicamente un rettangolo blu nel clip filmato base. Rispetto alla solita sintassi usata per disegnare le forme, abbiamo usato la proprietà command per spezzare il codice in due istruzioni separate. In questo modo potremo cambiare solo il colore del rettangolo senza doverlo istanziare da zero tutte le volte. A questo punto mancano solo le istruzioni che colorano lo sfondo in modo casuale. Completiamo il codice in questo modo:

var target = this.an;
stage.on("stagemousedown", function (e) {
var px=e.stageX;
var py=e.stageY;
var tween = createjs.Tween.get(target, {
 loop: false
})
 .to({
 x: px,
 y: py,
 }, 500, createjs.Ease.regular)
.call(cambia.bind(this)) 
});
// crea l'oggetto
var shape = new createjs.Shape();
var coloreCmd = shape.graphics.beginFill("#006699").command;
var rettangoloCmd = shape.graphics.drawRect(0,0,620,400).command; 
this.base.addChild(shape);
// cambia il colore
function cambia() {
var miorgb="#" + (Math.round(Math.random() * 0xffffff)).toString(16);
coloreCmd.style = miorgb; 
}

Prima di tutto abbiamo aggiunto l’istruzione call(cambia.bind(this)). Il metodo call esegue delle istruzioni quando l’animazione si interrompe. Nel nostro esempio attiviamo una funzione denominata cambia() il cui scopo è quello di modificare casualmente il colore del rettangolo. Alla variabile miorgb viene passato un colore esadecimale. Se masticate un pizzico di JavaScript potete notare come, grazie al metodo random della classe Math in associazione al metodo toString, otteniamo un valore esadecimale casuale al quale viene concantenata la stringa “#”.
Infine attraverso la proprietà style dell’oggetto coloreCmd, attribuiamo al rettangolo il nuovo colore.

Un menu elastico

Volendo possiamo anche controllare più oggetti animati con un solo evento. Cliccando QUESTO LINK trovate un menu che sfrutta un andamento elastico in uscita per comporsi in modo dinamico. Il principio alla base resta invariato, bisogna solo fare attenzione a coordinare correttamente le varie animazioni. Poiché il file si basa su una variante rispetto a quanto già visto, non ripercorreremo tutti vari passi, limitandoci ad analizzare i punti salienti del sorgente (che è possibile scaricare alla fine dell’articolo).
Il file prevede tre livelli denominati rispettivamente: sfondo, pulsanti e azioni. Nel primo livello abbiamo la solita firma che uso nei miei esempi, nel secondo gli elementi da animare e nel terzo un fotogramma chiave con il codice.

menu1Fig1
Gli elementi del secondo livello sono cinque: Il pulsante p_m, caratterizzato dalla scritta Menu posto al centro dello stage e altri quattro elementi collocati al di fuori dell’area visibile: p1, p2, p3 e p4. Cliccando una prima volta su Menu si genera un effetto in entrata con i pulsanti che si posizionano sotto quello principale in modo elastico tramite l’andamento Ease.elasticOut.
Cliccando una seconda volta, i pulsanti tornano ai lati dello stage con andamento regolare. L’esempio, per quanto semplicissimo, richiede un pizzico di accortezza nella gestione delle vari fasi. Per impedire effetti imprevisti, è molto importante che il tasto Menu non sia cliccabile fino a quando tutti e quattro i pulsanti non sono del tutto fermi. In altre parole devono smettere di rimbalzare completamente.
Inoltre, per evitare di scrivere un codice chilometrico, è stata usata una funzione denominata muovi() caratterizzata da quattro parametri:

function muovi(target,pos,t,tw){
var tween = createjs.Tween.get(target,{loop: false})
.to({x:pos, y:target.y,}, t,tw)
.call(nuovo.bind(this))
}

Per cui: target indica il pulsante da animare, pos la coordinata x che cambierà, t il tempo in millisecondi e tw l’andamento. Per cui, per animare il primo pulsante in entrata, invece di riscrivere tutto il codice ci basta un’istruzione di questo tipo:

muovi(this.p1,this.p_m.x,2000,createjs.Ease.elasticOut);

Questo codice ci dice che: ad essere animato è il pulsante p1, la posizione finale è la coordinata x del pulsante con la scritta menu, l’animazione dura 2 secondi e l’andamento è di tipo elastico in uscita. Trovate tutto il codice commentato passo dopo passo nel primo fotogramma del livello azioni. A questo proposito, ecco di seguito i link per scaricare i vari file:

Primo esempio: download.
Secondo esempio: download.
Terzo esempio: download.

E con questo è tutto. Nel prossimo articolo vedremo come usare Adobe Animate per progettare una minigallery scorrevole in HTML5 e createJS.

Share:

2 comments

  1. Enrico 5 agosto, 2016 at 15:41 Reply

    Sono capitato sul sito facendo delle ricerche con google. Gli esempi sono molto carini però non ho capito un paio di cose. Ci vuole Flash per creare questi effetti animati? Ho notato che non sono responsive, quindi non girano sugli smartphone?

    • bruno doper 5 agosto, 2016 at 15:51 Reply

      Gli esempi sono fatti con Adobe Animate (l’erede di Flash). Volendo si possono esportare in modalità responsive regolando il pannello di pubblicazione. Quindi funzionano anche sui dispositivi mobili. 🙂

Leave a reply

*