Menù 3D in Flash utilizzando le funzioni seno e coseno


Menù 3D in Flash utilizzando le funzioni seno e coseno

Con questo tutorial vedremo come ottenere un bell’effetto di profondità in Flash utilizzando le funzione matematiche seno e coseno.
No, non dovremo tornare a studiare trigonometria al liceo..l’utilizzo di questi 2 metodi della classe Math di ActionScript 2 è molto semplice e versatile: questo impiego per ricreare un menù apparentemente tridimensionale è solo uno dei molteplici effetti che possiamo ottenere.

L’effetto realizzato qui sopra è spiegato nelle relativamente poche righe di codice a seguire.
Tralascio o spiego in breve l’analisi di altre funzioni volendomi concentrare sull’ellisse creato dalle 2 funzioni matematiche SIN e COS.

import flash.filters.BlurFilter;
var links = new Array();
links[1] = ["http://www.w3facile.com/index.php/css-gallery", "CSS Gallery", "1"];
links[2] = ["http://www.w3facile.com/index.php/easy-bookmarker", "Easy Bookmarker", "2"];
links[3] = ["http://www.w3facile.com/index.php/enciclopedia-actionscript-20", "Enciclopedia Actionscript", "3"];
links[4] = ["http://www.w3facile.com/index.php", "HomePage", "4"];
var posX = Stage.width/2;
var posY = Stage.height/2+40;
var angle = links.length-1;
_global.rotating = true;
var mousePos = ((_root._xmouse-posX)/100);
sphere.swapDepths(999);

In un prossimo articolo voglio analizzare la classe che gestisce i filtri e provare qualche effetto ma per ora limitiamoci ad importare la classe per il blur dei movieclip quando vanno più in profondità, quindi creiamo un array di elementi, che saranno in questo caso le voci del nostro menù indicando URL, nome e un indice numerico o alfabetico che per ora non ci servirà.
Ho estrapolato questo esempio di codice da un ampio progetto e non mi sono preoccupato di togliere ogni riferimento esterno :)
Inserite le voci dichiariamo le variabili posX e posY, responsabili della centratura del menù al centro dello Stage.
In questo caso specifico faccio riferimento allo Stage perchè qui ho posizionato l’oggetto, nel caso vogliate creare un movieclip per importarlo dove volete ricordatevi di cambiare Stage con il nome del movieclip o con this.
Se dividendo ampiezza e altezza dello stage non doveste ottenere la giusta centratura perchè il menù ha una forma articolata, aggiustate facendo tentativi.
La variabile angle che dichiariamo corrisponde agli indici dell’array, vedremo poi come sarà implementata.
La variabile globale rotating ci serve per capire se la rotazione sta avvenendo o no, mousePos corrisponde alla posizione del mouse in relazione alle voci del menù, ci serve per regolare la velocità di rotazione intorno all’asse.
sphere.swapDepths(999) ci assicura che il livello di profondità del movieclip asse centrale sia quello giusto.

Richiamiamo le voci con questo ciclo:

for (var i = 1; i<angle+1; i++) {
attachMovie("menu", "menu"+i, i);
this["blur"+i] = new BlurFilter(5, 5, 2);
this["menu"+i].txtCover = i;
}

e instanziamo effetti blur per ogni movieclip che andremo poi a regolare in base alla profondità.

Passiamo alla funzione che gestisce il tutto, onEnterFrame:

this.onEnterFrame = function() {
if (rotating) {
mousePos -= ((_root._xmouse-posX)/100);

Se il boolean rotating è true, ovvero sta avvenendo la rotazione, ad ogni frame viene eseguito tutto lo script a seguire, mousePos viene aggiornato secondo la posizione del mouse sull’asse X.

E arriviamo al cuore e alla parte più difficile dello script:

for (var i = 1; i<angle+1; i++) {
depth = ((mousePos+(360/angle*i))*Math.PI)/(180);
this["menu"+i]._x = posX-(Math.sin(depth)*210);
this["menu"+i]._y = posY+(Math.cos(depth)*70);

In questo ciclo, per ogni voce del menù e quindi movieclip, assegniamo la profondità attuale e passandola come parametro (ovvero il grado vero e proprio dell’angolo che in quell’istante sta descrivendo l’orbita del movieclip) alle funzioni sin e cos otteniamo la posizione frame by frame del movieclipsullo stage. La funzione seno l’abbiamo impiegata per calcolare la posizione lungo l’asse X, la coseno per l’Y: provate a commentare la riga con la funzione coseno e vedrete che i movieclip cambiano solo la coordinata X rimanendo sempre sulla stessa Y, descrivendo comunque un cerchio regolare, un bell’effetto che però rende meno l’illusione dello spostamento lungo l’asse Z, quello della tridimensione.
Volendo dire un po’ di più ma consigliandovi comunque un approfondimento su libri specializzati, diciamo che il risultato della funzione seno in base al grado che passiamo restituisce un valore tra il numero massimo 1 e il numero minimo -1, che moltiplicato alla distanza che vogliamo e poi sottratto (o sommato se vogliamo rotazione antioraria) al centro del menù, ci restituisce la posizione lungo l’asse X.
Vi allego il grafico della funzione seno, chiamato in trigonometria sinusoide, per chi volesse capire meglio l’andamento del movieclip lungo l’asse X.

Grafico funzione sinusoide

La funzione coseno anch’essa oscilla tra i 1 e -1 ma in modo diverso in base al grado che passiamo e ci è utile per calcolare lo spostamento lungo l’asse Y senza ricalcolare la profondità ovvero il grado: controllare l’andamento nel grafico della cosinusoide qui sotto.

Grafico funzione cosinusoide

Anche il risultato del coseno viene moltiplicato per la distanza dal centro che scegliamo e poi sommato se vogliamo inclinazione dell’orbita verso il basso o sottratto per l’inclinazione verso l’alto.

this["menu"+i]._xscale = 100+(Math.cos(depth)*50);
this["menu"+i]._yscale = 100+(Math.cos(depth)*50);
this["menu"+i].swapDepths(1000+(Math.cos(depth)*100));
this["menu"+i].smoothing = true;

Per rendere ancora meglio l’effetto della tridimensione scaliamo i movieclip in base al grado e alla profondità, servendoci della funzione coseno per sottrarre o aggiungere valore al metodo x o yscale degli oggetti Flash, ovviamente lo scale dovrà essere lo stesso nello stesso istante e poi calcoliamo il diverso livello di profondità per sovrapporlo o non all’oggetto centrale del menù, in un modo simile a quello con cui calcoliamo lo scale.
Lo smoothing ci serve per nascondere i difetti dell’ingrandimento dei movieclip.

distance = this["menu"+i].getDepth()-900;
distance = Math.round(distance/40);
if (distance == 5) {
this["blur"+i].blurX = 0;
this["blur"+i].blurY = 0;
this["menu"+i].filters = [this["blur"+i]];
}
if (distance == 4) {
this["blur"+i].blurX = 1;
this["blur"+i].blurY = 1;
this["menu"+i].filters = [this["blur"+i]];
}
if (distance == 3) {
this["blur"+i].blurX = 2;
this["blur"+i].blurY = 2;
this["menu"+i].filters = [this["blur"+i]];
}
if (distance == 2) {
this["blur"+i].blurX = 3;
this["blur"+i].blurY = 3;
this["menu"+i].filters = [this["blur"+i]];
}
if (distance == 1) {
this["blur"+i].blurX = 4;
this["blur"+i].blurY = 4;
this["menu"+i].filters = [this["blur"+i]];
}
if (distance == 0) {
this["blur"+i].blurX = 5;
this["blur"+i].blurY = 5;
this["menu"+i].filters = [this["blur"+i]];
}

Quindi calcoliamo la distanza dal livello del centro del menù di ogni singolo movieclip secondo il livello di profondità su cui si trova, in base a questo valorizziamo l’effetto di Blur instanziato in precedenza e assegniamolo all’oggetto.
Questo è il momento giusto per inserire anche effetti diversi, sempre se vogliamo.

this["menu"+i].txtName = links[i][1].toUpperCase();
this["menu"+i].url = links[i][0];
this["menu"+i].onRelease = function() {
getURL(this.url, "_blank");
};
/*this["menu"+i].onRollOver = function():Void {
this["menu"+i].gotoAndPlay(2);
rotating = false;
};
this["menu"+i].onRollOut = function() {
rotating = true;
};*/
}
}
};
stop();

Assegniamo poi il nome del link per ogni singola voce del menù, la sua url e il click per aprire in una nuova finestra l’indirizzo selezionato.
Il codice commentato è un esempio di metodi di rollover e rollout associati ad animazioni all’interno del movieclip menù, dove la rotazione si interromperebbe per permettere una migliore visione della stessa.

Se necessario scaricate il codice sorgente clicca qui

Cerca: , , , , ,

Ritieni questo post utile o interessante?
Condividi e Segnala

Leggi anche:

5 commenti per “Menù 3D in Flash utilizzando le funzioni seno e coseno”

  1. flo ha detto:

    Troppo diffizile per me, ma il tuo plugin per Wordpress è fantastico ;)
    Ah… ti ho linkato, ciao!

  2. R.A.M. Page ha detto:

    Ti ho linkato anch’io :)

    Il plug-in l’ho ottimizzato e ci ho aggiunto altre cosette utili, poi quando ci risentiamo te lo passo
    Ciao!

  3. ale devartstudio ha detto:

    ciao
    complimenti…era proprio quello di cui avevo bisogno.
    Ho modificato il tuo script per fare una gallery dinamica da xml,
    e ho fatto un paio di modifiche, con il movimento del mouse allargo in entrambe le coordinate la larghezza della circonferenza creata!

    Terrò più d’occhio il tuo sito!
    Grazie

  4. R.A.M.Page ha detto:

    Piacere di esserti stato d’aiuto :)

  5. Rafael Dourado ha detto:

    Change if (distance == 5), if (distance == 4), if (distance == 3)…
    for this[”blur” + i].blurX = this[”blur” + i].blurY = Math.abs(distance - 5);

Rispondi al post