Questo è un classico esempio dove l'utilizzo di Actionscript permette di ottenere "il massimo della resa con poca spesa" rispetto ad un approccio misto con l'uso dell'interfaccia di Flash più qualche comando AS.
Non solo, Actionscript permette di realizzare un movie dinamico, svincolato dalle caratteristiche degli elementi particolari usati e quindi adattabile a qualsiasi altro oggetto senza bisogno di ulteriori modifiche.
Per realizzare questo movie col solo ausilio di Actionscript occorre innanzitutto studiarne prima la struttura ed il comportamento:
Abbiamo una serie di elementi (foto, movieclip o semplici riquadri) di dimensioni inferiori alla larghezza dello stage, ma comunque abbastanza larghi da non poter essere visualizzati tutti quanti per intero contemporeneamente.
Si tratta quindi di presentare tali elementi come fossero tante schede una sovrapposta all'altra lasciandone visibile una porzione di uguali simensioni. Al rollover su una di queste "schede" le altre si spostano consentendone così la visualizzazione completa.
Nell'esempio abbiamo:
> dimensioni stage stage: 640 x 300 px
> 4 foto di dimensione 400 x 300 px
La porzione "media" visibile di ogni foto (quando non c'è alcun roll-over) è pari a: 640/4 = 160px
La porzione "massima" è ovviamente la larghezza della singola foto: 400px
La porzione "minima" è quella che rimane visibile delle altre tre foto quando su una c'è il roll-over:
640 - 400 = 240 (spazio rimanente) / 3 = 80
Importo quindi le 4 foto in Flash, le converto in movieclip e le posiziono sullo stage attribuendo loro un nome istanza progressivo.
Nel mio caso: tab0, tab1, tab2, tab3.
Definisco quindi una Tabella (Array) dove memorizzare lo stato di roll-Over sulle schede che all'inizio è impostato su "False".
codice:
stato = new Array(false, false, false, false);
//
// calcolo porzioni visibili e posizione orizzontale
// la porzione "media" rappresenta la parte visibile quando nessuna scheda è in "roll-over"
// la porzione "minima" è la parte visibile delle altre schede quando una è in roll-over
// la porzione "massima" è, ovviamente, rappresentata dalla larghezza di ogni scheda
media = Stage.width / stato.length;
minima = (Stage.width - tab0._width) / (stato.length-1);
massima = tab0._width;
//
Ora mi serve un "prototype" per il movimento decelerato che richiamerò al momento opportuno quando dovrò
far spostare le schede.
codice:
//
// prototipo per il movimento decelerato
//
MovieClip.prototype.muovi = function (traguardo, speed) {
this.arrivato = false;
this.onEnterFrame = function () {
this._x = (traguardo - this._x) / speed + this._x;
if (Math.abs(traguardo-this._x)<=0.5) {
this._x = traguardo;
this.arrivato = true;
delete this.onEnterFrame;
}
}
}
Utilizziamo ora Actionscript per rendere i movieclip cliccabili come pulsanti...
Il funzionamento è il seguente:
> al roll-over il corrispondente elemento della tabella stato viene messo a "true"
> al roll-out il corrispondente elemento della tabella stato viene messo a "false"
codice:
//
// attivo i pulsanti delle schede (i clip sono nominati "tab0", "tab1" e così via...)
//
for (i=0; i<stato.length; i++) {
// al roll-over imposto il corrispondente elemento nella tabella Stato = true
this["tab"+i].onRollOver = function() {
ind = this._name.substr(3, 1);
stato[ind] = true;
}
// al roll-out imposto il corrispondente elemento nella tabella Stato = false
this["tab"+i].onRollOut = function() {
ind = this._name.substr(3, 1);
stato[ind] = false;
}
}
A questo punto mi serve una piccola funzione che, scandendo la tabella stato, mi restituisca il numero della scheda sulla quale c'è il rollover, oppure il valore -1 se il mouse è fuori dallo stage.
codice:
//
// Questa funzione scandisce la tabella di stato è mi fornisce
// -1 qualora nessun clip sia in stato di roll-over
// n il numero del clip in stato di roll-over
//
testato = function() {
// preimposto il risultato a -1 (nessun roll-over)
risultato = -1;
for (i=0; i<stato.length; i++) {
if (stato[i]) {
risultato = i;
}
}
return risultato;
}
I lavori preparatori sono così terminati, non rimane che scrivere il codice che fa funzionare il tutto, il "motore".
Ho scelto di definire una funzione legata all'evento "enterFrame" della _root in modo da poter tener sotto controllo in ogni istante lo stato delle cose.
codice:
//
this.onEnterFrame = function () {
// verifico lo stato delle schede
mousopra = testato();
if (mousopra != -1) {
//trace("il mouse è sopra un elemento");
for (z=0; z<stato.length; z++) {
if (z <= mousopra) {
this["tab"+z].muovi(z*minima, 5);
} else {
this["tab"+z].muovi(z*minima+massima-minima, 5);
}
}
} else {
//trace("il mouse è fuori");
for (z=0; z<stato.length; z++) {
this["tab"+z].muovi(z*media, 5);
}
}
}
//