Una classe countDown in Javascript

Lunedì 13 Ottobre, 2008

Nel post 3D CountDown con FIVe3D (vedi anche How I Did It: scrivere un countdown in Flash), veniva proposta una classe per la creazione di un oggetto CountDown in Actionscript, eccone una versione simile in Javascript:

JavaScript:
  1. /**
  2. * CountDown Class
  3. *
  4. * @author        Giovambattista Fazioli
  5. * @email         g.fazioli@undolog.com
  6. * @web           http://www.undolog.com
  7. *
  8. * @param    dd   (string) 'month day, year'
  9. *
  10. */
  11. function countDown( dd ) {
  12.     // init target time
  13.     var target            = new Date( dd );
  14.     this.targetTime        = target.getTime();
  15.    
  16.     /**
  17.      * refresh countdown
  18.      */
  19.     this.refresh = function() {
  20.         var today                 = new Date();
  21.         var currentTime           = today.getTime();
  22.         // time left
  23.         this._leftMilliseconds    = (this.targetTime - currentTime);
  24.         this._leftSeconds         = Math.floor( this._leftMilliseconds / 1000 );
  25.         this._leftMinutes         = Math.floor( this._leftSeconds / 60 );
  26.         this._leftHours           = Math.floor( this._leftMinutes / 60 );
  27.         // no module
  28.         this.leftDays             = Math.floor( this._leftHours / 24 );
  29.         // for print
  30.         this.leftMilliseconds     = this._leftMilliseconds % 1000;
  31.         this.leftSeconds          = this._leftSeconds % 60;
  32.         this.leftMinutes          = this._leftMinutes % 60;
  33.         this.leftHours            = this._leftHours % 24;
  34.     }
  35.     this.refresh();
  36. }

Esempio

JavaScript:
  1. var cd = new countDown( '1 1, 2009' );
  2. // mostra quanti giorni, ore, minuti, secondi e millisecondi al primo gennaio 2009
  3. document.write( cd.leftDays + "," + cd.leftHours + "," + cd.leftMinutes + "," + cd.leftSeconds + "," + cd.leftMilliseconds );

Post correlati

Scrivere buon codice OO in Adobe Flash

Venerdì 19 Ottobre, 2007

Ecco alcuni consigli su come scrivere un buon codice Object Oriented (OO) in Adobe Flash, soprattutto per chi ancora usa la versione MX in attesa di passare alla CS3.

Organizzare le cartelle delle classi

Prima di tutto l'organizzazione delle classi rende il lavoro di manutenzione del codice estremamente più semplice. Inoltre è possibile creare una vera e propria libreria personale da poter riutilizzare in altri progetti. Flash usa una nomenclatura legata al filesystem, quindi l'organizzazione in cartelle si rifletterà anche sull'importazione delle classi. Se ad esempio creiamo la sequenza di cartelle "mylibrary/grafica/plot" e inseriamo una nostra classe ActionScript "PlotClass.as", quando andremo ad importare la classe dovremmo usare:

Actionscript:
  1. import mylibrary.grafica.plot.PlotClass;

Se la libreria (cartella) "mylibrary" non si trova nella cartella del nostro filmato o progetto, usare l'impostazioni di pubblicazione di Flash per selezionare il percorso:

Impostazione percoroso librerie

Continua a leggere... »

Post correlati

ActionScript: _parent e controllo dei contesti

Mercoledì 22 Agosto, 2007

Quando "scatta" un evento di un oggetto il contesto, ovvero l'oggetto madre che rappresenta l'area di validità di tutte le variabili, diventa l'oggetto stesso. Questa caratteristica, propria della programmazioni Object Oriented, può disorientare provocando errori e malfunzionamenti nel codice. Inoltre, in determinate situazioni, può impedire di accedere ad alcune variabili "prima" disponibili.

Prima di tutto vediamo una caratteristica di ActionScript legata alla gestione dei contesti che, se compresa, ci farà risparmiare alcune ore di inutili prove. Quando abbiamo a che fare con oggetti grafici o più semplicemente di MovieClip innestati uno all'interno dell'altro, la proprietà _parent risolve qualsiasi problema di contesto. Ad esempio se il MovieClip padre_mc contiente un altro MovieClip figlio_mc e si usa il seguente codice:

Actionscript:
  1. // codice all'interno di padre_mc
  2. figlio_mc.onRelease = function() {
  3.     trace(this); // figlio_mc
  4.     trace(this._parent); // padre_mc
  5. }

Risalisre al "padre", quindi, risulta chiaro ed immediato.

Con classi pure, di solo codice, o estensioni di MovieClip, la proprietà _parent non è disponibile e le cose si potrebbero complicare! Immaginiiamo di avere una Classe MyClass:

Actionscript:
  1. Class MyClass extends MovieClip {
  2.     function MyClass() {
  3.         // constructor
  4.     }
  5.     //
  6.     function myMethod() {
  7.          trace(this); // myClass
  8.          var num = 5;
  9.          var cp = this;
  10.          ....
  11.          var myObject = new [ un oggetto ];
  12.          myObject.onLoad = function() {
  13.               trace(this); // myObject
  14.               trace(cp); // myClass
  15.          }
  16.     }

Il contesto di MyMethod() è, ovviamente, this, ovvero il puntatore alla classe MyClass. La variabile num, ad esempio, ha un ciclo di vita racchiuso all'interno del metodo MyMethod(). È visibile quindi solo all'interno del metodo e verrà distrutta all'uscita. Stessa cosa per la variabile myObject che tuttavia inizializza un evento, in questo caso onLoad. Quando scatterà onLoad() il contesto diventerà myObject lasciandoci, apparentemente, senza il puntatore alla classe madre myClass. Analizzando attentamente il codice ci accorgiamo che la variabile cp, definita nel metodo myMethod(), ha lo stesso contesto della variabile myObject! Infatti la variabile cp (class pointer) sarà visibile all'interno del metodo onLoad dell'oggetto myObject in quanto condivide con esso lo stesso contesto. In realtà il metodo myMethod() non viene deallocato proprio perchè l'oggetto myObject ha necessità di "vivere" più al lungo del previsto visto che ha "allocato" un evento (di tutto questo se ne occupa Flash a nostra "insaputa").

 

Consiglio

Per gli eventi legati a bottoni o a MovieClip una buona abitudine sarebbe quella di usare la forma:

Actionscript:
  1. my_mc.onRelease = myOnRelease;
  2. function myOnRelease() {
  3.     trace(this); // _root
  4.     trace("Click me");
  5. }

Al posto della più rapida ed immediata:

Actionscript:
  1. my_mc.onRelease = function() {
  2.     trace(this); // my_mc
  3.     trace("Click me");
  4. }

Il vantaggio di usare un funzione esterna è quella di avere un contesto neutro e la possibilità di accedere alla funzione a prescindere dal MovieClip che la controlla. Nel secondo caso, ad esempio, se volessi forzare l'esecuzione del codice legato al "click" del MovieClip dovrei usare un codice di questo tipo:

Actionscript:
  1. my_mc.onRelease();

In pratica chiamo l'evento come fosse un metodo. Tuttavia devo - appunto - avere a disposizione il MovieClip my_mc. Nell'altro modo, invece, posso eseguire il codice chiamando direttamente myOnRelease(). Ovviamente, come mostrato negli esempi, occhio ai contesti. Nel primo caso il contesto di myOnRelease() è quello dell'oggetto madre dove è scritto, ad esempio _root. Nel secondo caso, invece, il contesto è sempre il MovieClip my_mc!

 

Forzare un diverso contesto

Concludiamo con un tricks utile in molte circostanze. Flash mette a disposizione una libreria, mx.utils, con un oggetto Delegate in grado di forzare un contesto di un metodo o funzione. Il suo uso è davvero semplice:

Actionscript:
  1. import mx.utils.Delegate;
  2. //
  3. var my_mc; // puntatore ad un MovieClip
  4. var my_btn; // un bottone
  5. function myFunction() {
  6.     trace(this);
  7. }
  8. my_btn.onPress = Delegate.create(my_mc, myFunction);

L'evento onPress del bottone my_btn punta ad un "nuova" funzione creata appunto con il contesto my_mc. Quando si clicca sul bottone my_btn, il codice eseguito in myFunction() avrà come contesto my_mc!

Post correlati