In questo tutorial ti mostrerò come creare un menu come Dock di Apple usando le classi AS3. Creeremo un singolo file AS che eseguirà tutta la magia, estendendolo per aggiungere nuove funzionalità.
Tutorial ripubblicatoOgni poche settimane, rivisitiamo alcuni dei post preferiti del nostro lettore da tutta la cronologia del sito. Questo tutorial è stato pubblicato per la prima volta nel marzo del 2010.
Per prima cosa, diamo un'occhiata a cosa creeremo. Passa con il mouse sulle icone per vedere come si muovono e scalano.
Inizia creando un nuovo file ActionScript e salvandolo come "DockItem.as". Sto salvando il mio in c: /macmenu/org/effects/DockItem.as.
Si noti che la nostra root dei documenti (dove vive .fla) sarà c: / macmenu; la cartella / org / effetti formerà il pacchetto per la classe DockItem.
Crea un nuovo file Flash ActionScript 3.0 e aprilo, in modo che abbiamo sia DockItem.as che questo file .fla aperto. Salva questo .fla nella cartella radice (il DockItem.as è in c: / macmenu / org / effects, quindi la nostra radice del sito è c: / macmenu) il / org / effects è il pacchetto di Oggetto DockItem e salviamo il file. fla as c: /macmenu/macmenu.fla.
Ora importiamo o disegniamo alcune icone nel file .fla. Ho importato alcune icone che ho qui da un file di Illustrator, ma puoi ovviamente disegnare le tue e applicare loro un gradiente.
Seleziona qualsiasi icona e fai clic su Modifica> Converti in simbolo.
Nella casella che si apre, assegnagli un nome (ho chiamato questo simbolo "Star") e presta attenzione al punto di registrazione; deve essere in fondo al centro. Per la classe usa lo stesso nome (ricorda che non puoi usare spazi) e per la classe Base, usa org.effects.DockItem (la classe che creeremo). Inoltre, assicurati che il tuo tipo sia impostato su Movie Clip.
Quindi, allinea tutti gli oggetti in basso: seleziona tutto, fai clic su Finestra> Allinea, assicurati che il pulsante "In scena" non sia selezionato (altrimenti si allineerà sul fondo dello stage), quindi fai clic sul pulsante in alto a destra in questo pannello per allineare tutti gli oggetti.
Possiamo avere tutti i pulsanti che vogliamo, quindi convertiamo tutte le nostre icone in simboli. Ricordati di dare loro un nome e una classe, imposta tutti i loro punti di registrazione in basso al centro e imposta la classe Base su org.effects.DockItem.
Vedi sotto come dovrebbero apparire la nostra biblioteca e le icone; nota lo spazio tra di loro, è importante per creare un buon effetto.
Se testiamo il film ora genererà un errore dicendo che un file ActionScript deve avere almeno una definizione esterna e visibile; questo perché tutte le nostre voci di menu stanno estendendo la classe DockItem, che non abbiamo ancora scritto. Scriviamolo adesso ...
Inizia a creare il pacchetto estendendo la classe Sprite (estenderemo Sprite poiché non abbiamo un'animazione della timeline).
pacchetto org.effects import flash.display.Sprite; DockItem di classe pubblica estende Sprite
A questo punto abbiamo il nostro DockItem che estende la classe Sprite, quindi se lo provi ora funzionerà, ma non vedrai effetti.
(Confuso? Non usato per codificare con le classi? Dai un'occhiata a questo suggerimento rapido sull'uso di una classe di documenti per un'introduzione.)
Ora importeremo tutte le classi necessarie. Qui viene utilizzata una classe personalizzata, la classe TweenLite, che puoi scaricare da GreenSock.com. Dopo aver scaricato TweenLite, estrailo nella cartella / macmenu / (quindi avrai una cartella / macmenu / com / greensock /).
pacchetto org.effects import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import com.greensock.TweenLite; //http://www.greensock.com/tweenlite import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; DockItem di classe pubblica estende Sprite
Ho importato la classe Sprite perché è ciò che stiamo estendendo; se hai delle animazioni sulla timeline, estendi la classe MovieClip. Utilizzeremo la classe Event quando l'oggetto personalizzato verrà aggiunto allo stage e utilizzeremo MouseEvent quando controlliamo la distanza di ciascuna icona dal mouse.
Durante questo passaggio dichiareremo le variabili necessarie:
pacchetto org.effects import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; public class DockItem estende Sprite private var _initPosition: Number; public var maxXDistance: Number; public var maxYDistance: Number; public var maxScale: Number;
Nota che ho usato il _initPosition come privato: imposta solo la posizione iniziale dell'icona. La distanza del mouse sarà sempre misurata da questo punto, poiché la posizione x effettiva dell'elemento cambierà sempre.
maxXDistance è la distanza x massima su cui il mouse influenzerà l'icona, maxYDistance è la distanza massima su cui il mouse influenzerà l'icona e maxScale è la scala massima che verrà aggiunta all'icona (ad esempio, se la si imposta su 2, la scala massima che l'oggetto può raggiungere è 3.)
Ho usato variabili pubbliche per gli ultimi tre in modo che possiamo cambiarli in fase di esecuzione.
La funzione di costruzione deve avere lo stesso nome della classe (e quindi lo stesso nome del file), quindi DockItem ():
pacchetto org.effects import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; public class DockItem estende Sprite private var _initPosition: Number; public var maxXDistance: Number; public var maxYDistance: Number; public var maxScale: Number; funzione pubblica DockItem ($ maxXDistance: Number = 60, $ maxYDistance: Number = 30, $ maxScale: Number = 2): void maxXDistance = $ maxXDistance; maxYDistance = $ maxYDistance; maxScale = $ maxScale; if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init); addEventListener (Event.REMOVED_FROM_STAGE, end);
Perché abbiamo alcuni parametri qui? Questo ci permette di utilizzare diverse combinazioni di distanze e scale: possiamo avere una breve distanza con una scala molto grande o una lunga distanza con una scala ridotta. Inoltre, possiamo determinare la distanza entro cui il mouse influenzerà l'icona.
Mentre estendiamo la classe Sprite, possiamo aggiungere bambini o anche codificare una classe personalizzata per ogni icona che estende la classe DockItem, quindi se la estendiamo possiamo usare la funzione super () per passare i nuovi parametri alla superclasse. Possiamo quindi utilizzare la classe DockItem sempre e ovunque.
In questo passaggio impostiamo la variabile maxXDistance, la variabile maxYDistance e la variabile maxScale sui valori passati come parametri. Inoltre, controlliamo se l'oggetto è sul palco - in caso contrario, aggiungiamo un evento per verificare quando è. Aggiungiamo anche un altro listener di eventi per rilevare quando l'icona viene rimossa dallo stage. Aggiungeremo un evento MOUSE_MOVE sul palco per ottenere la distanza, quindi è importante sapere se è sul palco.
Questa è la funzione che verrà eseguita una volta che l'icona è stata creata e aggiunta allo stage. Nella funzione init () aggiungiamo semplicemente un listener MouseEvent.MOUSE_MOVE allo stage, impostiamo la variabile _initPosition sul valore x dell'oggetto e ascoltiamo che il mouse lasci l'area dello stage.
pacchetto org.effects import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; public class DockItem estende Sprite private var _initPosition: Number; public var maxXDistance: Number; public var maxYDistance: Number; public var maxScale: Number; funzione pubblica DockItem ($ maxXDistance: Number = 60, $ maxYDistance: Number = 30, $ maxScale: Number = 2): void maxXDistance = $ maxXDistance; maxYDistance = $ maxYDistance; maxScale = $ maxScale; if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init); addEventListener (Event.REMOVED_FROM_STAGE, end); funzione privata init (e: Event = null): void _initPosition = x; stage.addEventListener (MouseEvent.MOUSE_MOVE, mouseMove); stage.addEventListener (Event.MOUSE_LEAVE, mouseLeave);
Quando il mouse si sposta sullo stage, questa funzione (attivata dall'evento MOUSE_MOVE abbiamo aggiunto un listener per l'ultimo passaggio) controllerà la posizione del mouse dell'oggetto padre e misurerà la distanza dall'oggetto alla posizione padre del mouse.
Usiamo parent.mouseX perché questo ci porta la posizione x del mouse rispetto a qualsiasi oggetto contenga l'icona, piuttosto che rispetto al punto di registrazione dell'icona.
Abbiamo anche tweenare le icone nelle loro posizioni iniziali se il mouse lascia il palco nel gestore di mouseLeave ().
pacchetto org.effects import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; public class DockItem estende Sprite private var _initPosition: Number; public var maxXDistance: Number; public var maxYDistance: Number; public var maxScale: Number; funzione pubblica DockItem ($ maxXDistance: Number = 60, $ maxYDistance: Number = 30, $ maxScale: Number = 2): void maxXDistance = $ maxXDistance; maxYDistance = $ maxYDistance; maxScale = $ maxScale; if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init); addEventListener (Event.REMOVED_FROM_STAGE, end); funzione privata init (e: Event = null): void _initPosition = x; stage.addEventListener (MouseEvent.MOUSE_MOVE, mouseMove); stage.addEventListener (Event.MOUSE_LEAVE, mouseLeave); private function mouseMove (e: MouseEvent): void var yDistance: Number = Math.abs (parent.mouseY-y); if (yDistance> maxYDistance) if (_initPosition == x) return; else TweenLite.to (this, .3, x: _initPosition, scaleX: 1, scaleY: 1); ritorno; // ottiene la differenza tra la posizione x del mouse genitore e la posizione iniziale dell'oggetto var xDistance: Number = parent.mouseX-_initPosition; // controlla se la distanza del mouse dall'oggetto è maggiore della distanza massima, non può essere più grande ... xDistanza = xDistanza> maxXDistanza? maxXDistance: xDistance; // controlla se la distanza è inferiore al negativo della distanza massima, non può essere inferiore ... xDistanza = xDistanza < -maxXDistance ? -maxXDistance : xDistance; //create a variable for the position, assuming that the x position must be the initial position plus the distance of the mouse, but it can't be more than the max distance. var posX=_initPosition-xDistance; //we get the scale proportion here, it goes from 0 to maxScale variable var scale:Number=(maxXDistance-Math.abs(xDistance))/maxXDistance; //the minimum scale is 1, the original size, and the max scale will be maxScale variable + 1 scale=1+(maxScale*scale); //here we use a Tween to set the new position according to the mouse position TweenLite.to(this,.3,x:posX,scaleX:scale,scaleY:scale); private function mouseLeave(e:Event):void TweenLite.to(this,.3,x:_initPosition,scaleX:1,scaleY:1);
Per prima cosa, controlliamo la distanza y (distanza verticale tra l'icona e il mouse); se è più lontano rispetto all'intervallo impostato con maxYDistanceVariable, controlliamo se l'icona è tornata nella sua posizione originale e, in caso contrario, l'abbiamo interpolata lì. Il ritorno parola chiave interrompe la funzione, quindi in questo caso non verrà eseguito il resto del codice.
Se il mouse è vicino all'icona verticalmente, usiamo alcuni calcoli per capire una nuova scala e la posizione per l'icona in base alla sua distanza orizzontale dal mouse, quindi tweenare a quei valori.
Se rimuoviamo l'oggetto dallo stage, dobbiamo rimuovere mouseMove e mouseLascia ascoltatori; in caso contrario, possiamo ottenere errori ogni volta che il mouse viene spostato. Questa funzione è il gestore per il listener REMOVED_FROM_STAGE che abbiamo aggiunto in precedenza, quindi verrà attivato quando l'oggetto viene rimosso.
pacchetto org.effects import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; public class DockItem estende Sprite private var _initPosition: Number; public var maxXDistance: Number; public var maxYDistance: Number; public var maxScale: Number; funzione pubblica DockItem ($ maxXDistance: Number = 60, $ maxYDistance: Number = 30, $ maxScale: Number = 2): void maxXDistance = $ maxXDistance; maxYDistance = $ maxYDistance; maxScale = $ maxScale; if (stage) init (); else addEventListener (Event.ADDED_TO_STAGE, init); addEventListener (Event.REMOVED_FROM_STAGE, end); funzione privata init (e: Event = null): void _initPosition = x; stage.addEventListener (MouseEvent.MOUSE_MOVE, mouseMove); stage.addEventListener (Event.MOUSE_LEAVE, mouseLeave); private function mouseMove (e: MouseEvent): void var yDistance: Number = Math.abs (parent.mouseY-y); if (yDistance> maxYDistance) if (_initPosition == x) return; else TweenLite.to (this, .3, x: _initPosition, scaleX: 1, scaleY: 1); ritorno; // ottiene la differenza tra la posizione x del mouse genitore e la posizione iniziale dell'oggetto var xDistance: Number = parent.mouseX-_initPosition; // controlla se la distanza del mouse dall'oggetto è maggiore della distanza massima, non può essere più grande ... xDistanza = xDistanza> maxXDistanza? maxXDistance: xDistance; // controlla se la distanza è inferiore al negativo della distanza massima, non può essere inferiore ... xDistanza = xDistanza < -maxXDistance ? -maxXDistance : xDistance; //create a variable for the position, assuming that the x position must be the initial position plus the distance of the mouse, but it can't be more than the max distance. var posX=_initPosition-xDistance; //we get the scale proportion here, it goes from 0 to maxScale variable var scale:Number=(maxXDistance-Math.abs(xDistance))/maxXDistance; //the minimum scale is 1, the original size, and the max scale will be maxScale variable + 1 scale=1+(maxScale*scale); //here we use a Tween to set the new position according to the mouse position TweenLite.to(this,.3,x:posX,scaleX:scale,scaleY:scale); private function mouseLeave(e:Event):void TweenLite.to(this,.3,x:_initPosition,scaleX:1,scaleY:1); private function end(e:Event=null):void stage.removeEventListener(MouseEvent.MOUSE_MOVE,mouseMove); stage.removeEventListener(Event.MOUSE_LEAVE,mouseLeave);
Tutto ciò che facciamo in questa funzione è rimuovere il listener di eventi dallo stage.
A questo punto possiamo già testarlo; funzionerà poiché ogni oggetto è collegato alla classe Base DockItem. Tuttavia, non abbiamo una casella di delimitazione per fare clic (se impostiamo il nostro oggetto buttonMode proprietà true, vedremo che possiamo fare clic su di esso solo quando è sopra l'immagine reale.)
Finora possiamo vedere l'effetto funzionare, quindi ora trasformiamo ciascun elemento in un pulsante. Creeremo un nuovo file ActionScript e questo estenderà DockItem: chiamiamolo DockButton. Il suo pacchetto sarà lo stesso di DockItem (org.effects), quindi salveremo itb nella stessa cartella di DockItem.as (esempio: c: /macmenu/org/effects/DockButton.as)
Ora cambiamo la classe base di ogni oggetto nella libreria. Attualmente stiamo usando org.effects.DockItem come classe Base, utilizziamo ora org.effects.DockButton.
Se lo proviamo ora, ci sarà un errore. Questo perché DockButton.as è ancora vuoto, quindi scriviamolo.
OK, ora estenderemo la classe DockItem, perché vogliamo utilizzare tutto ciò che abbiamo in DockItem e aggiungere altri trucchi (permettendogli di agire come un pulsante), ma non vogliamo aggiungere le nuove funzionalità a DockItem direttamente. In questo modo, se vogliamo usare DockItem come qualcosa di diverso da un Button in un secondo momento, possiamo, ma se vogliamo usarlo come Button possiamo usare il DockButton.
pacchetto org.effects DockButton di classe pubblica estende DockItem
Se testiamo il nostro progetto ora, funzionerà, ma funzionerà esattamente come DockItem dato che non abbiamo ancora aggiunto nulla di nuovo.
Importiamo alcune cose che avremo bisogno di estendere il DockItem. Poiché stiamo estendendo DockItem, non abbiamo bisogno di importare le classi che sono già lì, poiché non le useremo direttamente in DockButton.
pacchetto org.effects import flash.geom.Rectangle; DockButton di classe pubblica estende DockItem
Ho importato la classe Rectangle, ma perché? È perché useremo il riquadro di delimitazione del nostro oggetto per creare uno sfondo falso, per consentire al pulsante di essere cliccabile anche se il mouse non si trova esattamente su un'area colorata. Creiamo un grafico di sfondo con alpha 0 (trasparente), quindi avremo un quadrato su cui fare clic.
Poiché abbiamo bisogno di creare un riquadro di delimitazione per DockButton, otterremo i suoi limiti, ecco perché abbiamo importato la classe flash.geom.Rectangle
pacchetto org.effects import flash.geom.Rectangle; DockButton di classe pubblica estende DockItem funzione pubblica DockButton (): void buttonMode = true; mouseChildren = falso; var limits: Rectangle = getBounds (this); this.graphics.beginFill (0,0); this.graphics.drawRect (bounds.x, bounds.y, bounds.width, bounds.height); this.graphics.endFill ();
Cosa abbiamo fatto? Abbiamo creato un costruttore che prima imposta il pulsante buttonMode su true, quindi il nostro DockButton verrà trattato come un pulsante. Quindi impostiamo mouseChildren su false, quindi gli eventi del mouse verranno dall'oggetto DockButton e non da qualsiasi altro oggetto al suo interno. Successivamente otteniamo i limiti dell'oggetto usando getBounds () e disegniamo un rettangolo trasparente usando l'oggetto grafico. (La proprietà grafica viene fornita con la classe Sprite e abbiamo esteso Sprite per rendere il nostro oggetto DockItem. Ora abbiamo esteso il nostro DockItem per rendere il nostro oggetto DockButton, DockButton ha tutto dalla classe Sprite e dalla classe DockItem.)
OK, eseguiamo un controllo:
Se tutto va bene, prova il film ...
(A questo punto, se vuoi mettere la cartella org / effetti nel tuo classpath puoi, non avrai bisogno di copiare questa cartella in ogni progetto che crei e usa DockItem o DockButton.)
Perché non cambiare il colore del pulsante quando il mouse lo passa sopra? In questa sezione insegnerò come. Per questo useremo di nuovo il motore TweenLite per dare un po 'di tinta all'oggetto. Tuttavia, stiamo già utilizzando TweenLite nell'oggetto DockItem e stiamo estendendo questo oggetto a DockButton. Vogliamo estendere DockButton per cambiare il colore, ma non possiamo più utilizzare TweenLite nello stesso oggetto poiché il nuovo oggetto TweenLite sovrascriverà l'altro (anche con la proprietà sovrascrivere: false in TweenLite ridurrà molto le prestazioni se lo utilizziamo direttamente nello stesso oggetto). Non è tutto perduto; abbiamo un'icona all'interno di ogni oggetto della libreria e possiamo applicare la tinta a questo.
Per fare ciò, creiamo un altro file ActionScript, ma ora salvalo nella stessa cartella di .fla con il nome "OverButton.as" (esempio: c: /macmenu/OverButton.as.)
Per prima cosa creiamo il pacchetto e importiamo le classi necessarie; dato che abbiamo salvato il file OverButton.as nella stessa cartella del file .fla, il pacchetto sarà di primo livello, quindi non è necessario scrivere "pacchetto org.effects":
package import org.effects.DockButton; import flash.display.DisplayObject; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; OverButton di classe pubblica estende DockButton
OK, quindi questa volta estendere DockButton e abbiamo importato la classe DisplayObject perché considereremo l'icona come DisplayObject. Abbiamo anche importato MouseEvent che useremo per controllare quando il mouse è sopra l'icona e quando è fuori. Abbiamo anche TweenLite per creare alcuni effetti di interpolazione con il colore.
package import org.effects.DockButton; import flash.display.DisplayObject; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; OverButton di classe pubblica estende DockButton private var _object: DisplayObject; funzione pubblica OverButton (): void _object = this.getChildAt (0) come DisplayObject; this.addEventListener (MouseEvent.MOUSE_OVER, mouseOver); this.addEventListener (MouseEvent.MOUSE_OUT, mouseOut); TweenPlugin.activate ([TintPlugin]);
Perché abbiamo creato un oggetto privato _oggetto come DisplayObject? La nostra icona attuale è memorizzata in questa variabile (è ciò che fa la riga 13) e viene trattata come DisplayObject; useremo l'effetto colore sulla nostra icona, non sull'intero oggetto.
Aggiungiamo i listener di eventi del mouse per controllare quando il mouse è finito e quando il mouse è fuori.
Dal momento che abbiamo creato gli ascoltatori per il mouse e il mouse, creeremo ora le loro funzioni:
package import org.effects.DockButton; import flash.display.DisplayObject; import flash.events.MouseEvent; import com.greensock.TweenLite; import com.greensock.plugins.TweenPlugin; import com.greensock.plugins.TintPlugin; OverButton di classe pubblica estende DockButton private var _object: DisplayObject; funzione pubblica OverButton (): void _object = this.getChildAt (0) come DisplayObject; this.addEventListener (MouseEvent.MOUSE_OVER, mouseOver); this.addEventListener (MouseEvent.MOUSE_OUT, mouseOut); TweenPlugin.activate ([TintPlugin]); funzione privata mouseOver (e: MouseEvent): void new TweenLite (_object, .5, tint: 0x990099); funzione privata mouseOut (e: MouseEvent): void new TweenLite (_object, .5, tint: null);
Nota che stiamo usando TweenLite su _object ora, non su "this" più. Questo perché OverButton estende il DockButton che estende DockItem dove è già in uso un TweenLite. Inoltre, in DockButton abbiamo uno sfondo alfa 0 falso che non ha bisogno di essere dipinto.
Per la proprietà tint di TweenLite ho usato un codice colore di 0x990099, che è un viola medio; se usi null come il valore che la tinta sarà rimossa dolcemente.
A questo punto, se esegui il test del film, non vedrai alcun cambiamento di colore, perché abbiamo bisogno di cambiare di nuovo la classe base di ogni oggetto nella libreria. Apri la Libreria ancora una volta in .fla (Finestra> Libreria). Fai clic con il pulsante destro del mouse su ciascun oggetto e modifica la sua classe base su OverButton (non org.effects.OverButton, perché il file di classe non si trova nella cartella / org / effects).
OK, ora puoi testarlo!
In questo tutorial ho spiegato sull'estensione degli oggetti. L'effettivo effetto dock è pura matematica - si tratta di calcoli a distanza, impostazioni di scala - ma è importante notare nel codice che non possiamo usare la proprietà "x" come riferimento di posizione, poiché la proprietà "x" viene cambiata ogni volta. Spero che ora tutti voi possiate comprendere meglio la parola chiave "estende" e apprezzate come vengono effettuati i calcoli qui. Grazie per aver letto :)