Dalle varie richieste viste sul forum Macromedia Flash, su come realizzare una galleria di immagini, come inserire dei testi associati alle immagini, ridimensionare foto grandi, fare uno zoom della miniatura, ho pensato di creare questo semplice tutorial che raccolga tutte queste informazioni.
Semplice, perchè indubbiamente esisteranno modi più raffinati ed ottimizzati in termini di AS e di struttura, tuttavia ritengo sia un punto di partenza, sul quale lavorare. Molti degli argomenti/funzioni che verranno trattati sono stati già ampiamente descritti in altri tutorial specifici e/o guide di questo sito, quindi mi limiterò alla descrizione di come progettare e realizzare una galleria di immagini. Elementi su cui iniziare a ragionare, prima di buttarsi a capofitto su animazioni e codice:
- Dimensioni dello foto e dello stage, affinchè miniature ed ingrandimenti rientrino esattamente nel filmato.
- Utilizzo di denominazioni standardizzate delle immagini. Quindi impiego di file txt o database che contengano le informazioni.
- Disegnare il layout per le miniature, per le immagini e per le informazioni. Analizzati e definiti questi tre elementi, stabiliamo che avremo
-
- foto sviluppate in orizzontale 320 x 200
- 6 miniature contemporanee sullo stage 100 x 70
- uno spazio adeguato per le informazioni relative alle immagini 200 x 350
- uno spazio per le pagine relative ai blocchi delle miniature N x 6
Ottenendo quindi un layout di questo tipo:
Iniziamo con il creare il movieClip che conterrà le miniature ed un campo testo. Esempio: codiceChiameremo il clip con istanza MINI (100 x 70) e questo sarà composto da almeno due livelli sovrapposti:
- clip IMG istanza IMG dimensioni 80 x 56 - rettangolo traformato in clip registrato in _x=10, _y=7
- clip SFONDO istanza SFONDO dimensioni 100 x 70 - rettangolo traformato in clip registrato in 0,0 come da figura.
A questo punto lo mettiamo nella libreria e lo Linkiamo con "MINI" per utilizzo tramite AS (metodo attachMovie).
Creazione miniature
Abbiamo detto che sullo stage avremo solo 6 Miniature alla volta, quindi nel caso di 60 foto avremo la necessita di far scorrere 10 blocchi di miniature.
Raccogliamo le nostre foto in una cartella Foto, verifichiamo che le jpg siano non progressive e che abbiano un rapporto oriz/vert = 1,6 in modo tale che il ridimensionamento con AS non le deformi troppo. Al momento nominiamole come una successione alfa-numerica Es: image01.jpg......image60.jpg
Al momento di provare il codice, utilizzero un file TXT ove raccogliere le informazioni, in seguito potremo utilizzare un Dbase ed una pagina ASP che lo sostituisca. Ovviamnte il contenuto del TXT così come lo scriverò potrebbe - a molti - risulare inutile. Tuttavia c'è sempre la possibilità che le foto possano avere nomi differenti, quindi ecco il perchè dell'utilizzo del file esterno. Dati.txt, conterrà
&img1=image01.jpg&cat1=Cat. Lavoro &desc1=Metro Avvolgimento con blocco&Drive1=Giallo&dim1=Lunghezza 5 mt.&
&img2=image02.jpg&cat2=Cat. Meccanica &desc2=Chiave Tubolare con Crick &Drive2=Acciaio&dim2=Esagonale Mis. 12&
&img3=image03.jpg&cat3=Cat. Legno &desc3=Sega a Spada &Drive3=Acciaio &dim3=Dente 7 - 40cm.&
&img4=image04.jpg&cat4=Cat. Lavoro &desc4=Pinza Impugnatura Gomma &Drive4=Acciaio&dim4=Dim. 20 x 5 &
&img5=image05.jpg&cat5=Cat. Lavoro &desc5=Squadretta &Drive5=Acciaio &dim5=Dim. 20 x 20&
&img6=image06.jpg&cat6=Cat. Lavoro &desc6=Martello Cantiere &Drive6=Acciaio e Gomma&dim6=Dim.12 x 40&
&img7=image07.jpg&cat7=Cat. Lavoro &desc7=Cacciavite Piatto &Drive7=Acciaio&dim7=Dim 0.75 x 20&
&img8=image08.jpg&cat8=Cat. Giardinaggio&desc8=Paletta Giardino &Drive8=Acciaio e Legno&dim8=Dim. 4 x 20&
&img9=image09.jpg&cat9=Cat. Giardinaggio&desc9=Secchio Alluminio &Drive9=Manico ad Arco&dim9=Dim 25 x 30&
&totale=9&
Per ottenere lo stesso risultato del contenuto del TXT mediante pagina ASP e DB Access un esempio potrebbe essere:
<%@LANGUAGE="VBSCRIPT"%>
<!-- #include file="adovbs.inc" -->
<%
Response.Expires = 0
dim DSNName, sql
'set DSNName =Server.CreateObject("ADODB.Connection")
DSNName = "DRIVER={Microsoft Access Driver (*.mdb)};DBQ="
DSNName = DSNName & Server.MapPath("/mdb-database/") & "ferramenta.mdb;pwd=guest"
sql = "SELECT * FROM viti ORDER BY viti.idcod Asc"
Set rs = Server.CreateObject("ADODB.Recordset")
rs.ActiveConnection = DSNName
rs.Source = sql
rs.CursorType = 0
rs.CursorLocation = 2
rs.LockType = 1
rs.Open()
'function start
x = 0
while not rs.eof
x = x + 1
Response.Write("img" & x & "=" & rs("image")& "&cat" & x & "=" & rs("categ")& "&descl" & x & "=" & rs("descrizione")& "&drive" & x & "=" & rs("drive")& "&dim" & x & "=" & rs("dimensioni"))
rs.MoveNext
Response.Write("&")
wend
get_number_of_recordset = x
Response.write("Totale="& get_number_of_recordset & "&")
'end function
rs.Close
Set rs=Nothing
%>
Le MINIATURE quindi verranno inserite all'interno di un BOX e posizionate in base ad un ciclo che prevederà dei controlli sulle posizioni di colonne e righe. Le Miniature scorreranno in verticale di 6 elementi alla volta tramite dei pulsanti (PAG) Poichè lo script le posizionerà tutte all'interno di BOX sarà quindi necessario mascherarle tramite il clip MASK, delle dimensioni si 6 box per miniature.
Analogamente alla Mask per le miniature dobbiamo prevedere una mashera per i pulsanti dinamici che ci permetteranno di navigare le miniature. Ovviamente il tutto si può realizzare con due semplici bottoni. In questo tutorial l'ho realizzato graficamente con dei foglietti (PAG) che funzioneranno da pulsanti.
Iniziamo con la prima parte di AS. Potrebbe essere che parte di questo tutorial debba inserirlo in altri progetti, pertanto preferisco scrivere una funzione richiamabile in qualsiasi momento.
/*
Per comodità le Maschere MaskMINI e MaskPAG le creo graficamente
*/
function Crea_Box(){ // creo un clip contenitore per Miniature
this.createEmptyMovieClip("MainMINI",1)
this.MainMINI._x=this.MaskMINI._x=11
this.MainMINI._y=this.MaskMINI._y=210
// lo maschero per eventuali miniature superiori 6
this.MainMINI.setMask(MaskMINI)
// creo un clip contenitore per le Pagine
this.createEmptyMovieClip("MainPAG",2)
this.MainPAG._x=this.MaskPag._x=60
this.MainPAG._y=this.MaskPag._y=365
// lo maschero se il numero dei foglietti superiori ad 8
this.MainPAG.setMask(MaskPAG) }
Crea_Box()
Creati i contenitori, adesso dovremo affrontare il problema di come:
- prendere dalla libreria i clip MINI
- posizionarli sullo Stage
- leggere i dati dall'esterno tramite loadVars()
- popolare i clip con le immagini
- scalare le immagini
- eseguire il preload di ogni immagine
- far apparire correttamente l'immagine in FadeIn
- creare la funzione per aprire l'immagine a dimensioni reali cliccando sulle miniature.
Iniziamo con il dichiarare la funzione loadVars():
miniature=new LoadVars()
miniature.onLoad=function(success){
if(success){
// qui metteremo la funzione di caricamento Pagine e DATI che vedremo di seguito
}
}
miniature.load("dati.txt") // in alternativa miniature.load(dati.asp)
Prima di procedere realizziamo un piccolo Clip "PAGINE" composto da uno sfondo ed un campo variabile di testo chiamato "pag", che riceverà il numero progressivo delle pagine. Lo linkiamo con il nome "pagine" e lo lasciamo nella libreria.
Analizzando i dati che arrivano dal TXT l'emento che utilizzeremo per verificare quante pagine saranno (blocchi da 6 miniature) ed il parametro di raffronto per il ciclo di posizionamento delle miniature è la variabile TOTALE, quindi:
// CARICAMENTO PAGINE
// Calcolo quante pagine da 6 Miniature mi servono
pagine = Math.round(this.Totale/6)//+1
for(z=1; z<=pagine; z++){
// attacco il clip/bottone Pagine dalla Lib
MainPAG.attachMovie("pagine","pag"+z,z)
MainPAG["pag"+z].pag=z
MainPAG["pag"+z]._x=30*z-30
MainPAG["pag"+z]._y=0
MainPAG["pag"+z].protopag() // questo prototype verrà analizzato alla fine del tutorial
}
Vediamo separatamente le varie parti della condizione While, quindi il solo posizionamento delle miniature.
// POSIZIONAMENTO BOX MINIATURE
i =1 // contatore clip
j =1 //contatore di riga
k=1 //contatore di colonna
while(i <= this.Totale) {
MainMINI.attachMovie("MINI","MINI"+i,i)
mc=MainMINI["MINI"+i]
mc._x=k*110-110 // parto da _x=0
mc._y=j*80-80 // parto da _y=0
// all'interno di questo spazio inseriremo il caricamento dei dati, immagini e preload
// controlli per mandare a capo le miniature creando una struttura 3 x N
if(k<3){
k++
}else{
k=1;
j++
}
i++
} // Fine while(i <= this.Totale)
Una volta posizionati i clip MINI, possiamo passare al caricamento delle informazioni. Ricordo che siamo sempre all'interno della funzione loadVars(), quindi è necessario far riferimento a "miniature"
// CARICAMENTO DATI, IMMAGINI e PRELOAD
// carico sul clip tutti i dati relativi alla scheda
mc.img = this["img"+i]
mc.cat = this["cat"+i]
mc.desc = this["desc"+i]
mc.drive = this["drive"+i]
mc.dim = this["dim"+i]
// carico nel clip Foto, contenuto in MINI l'immagine
mc.foto.loadMovie("foto/"+this["img"+i])
// pongo l'alpha a zero per aver modo di eseguire prima il preload ed il dimensionamento.
mc.foto._alpha=0
// per comodo registro in ID il valore numerico che compone il nome del clip
mc.ID=i
// eseguo il controllo del preload
mc.onEnterFrame=function(){
if(this.foto.getBytesLoaded()>1024 && this.foto.getBytesLoaded() == this.foto.getBytesTotal()){
// calcolo dimensioni originali della foto
this.larg=this.foto._width
this.alt=this.foto._height
// chiamo la funzione di re-dimensionamento
this.foto._xscale = Math.floor(80/this.larg*100)
this.foto._yscale = Math.floor(56*100/this.alt*100)
// ridondante ma ci assicuriamo che siano esattamente rispettate le dimensioni
this.foto._width=80
this.foto._height=56
//eseguo la funzione di Fade IN
this.foto.onEnterFrame = function(){
// enterFrame per aumentare gradualmente l'alpha dell'immagine caricata
if(this._alpha < 100){this._alpha+=20;}
else {this._alpha = 100; delete this.onEnterFrame;}
}
// OPZIONE -----------------------------------------------------
// per far apparire automaticamente la prima foto
if(this.ID==1){
carica_foto(this.img)
carica_dati(this.img, this.cat,this.desc,this.drive,this.dim)
}
// Fine Opzione --------------------------------------------------
delete this.onEnterFrame // cancello l'enter frame alla fine del preload
} // fine IF
// OPZIONE --------------------------------------------------------
/*
Volendo si può inserire un clip barra all'interno di MINI per indicare l'avanzamento del preload quindi :
this.barra._xscale =Math.floor(this.foto.getBytesLoaded()/ this.foto.getBytesTotal()*100)
*/
// Fine Opzione-----------------------------------------------------
} // Fine mc.onEnterFrame=function()
// FUNZIONE DI CARICAMENTO FOTO GRANDE E DATI
mc.onPress=function(){
// chiamata
carica_foto(this.img)
carica_dati(this.img, this.cat,this.desc,this.drive,this.dim)
}
Per riassumere e dare una visione macro dell'intera funzione riepilogo in questo modo
miniature=new LoadVars()
miniature.onLoad=function(success){
if(success){
// qui metteremo la funzione di caricamento Pagine e DATI che vedremo di seguito
- Funzione CARICAMENTO PAGINE
- Funzione POSIZIONAMENTO MINIATURE
- CARICAMENTO DATI ED IMMAGINI
- PRELOAD IMMAGINI
- FADE IN (_alpha) IMMAGNI TRASFORMAZIONE MINIATURE IN PULSANTI
- Fine Posizionamento
}
}
miniature.load("dati.txt") // in alternativa miniature.load(dati.asp)
Prima di procedere con le parti restanti dell'AS, ovvero definire le due funzioni di caricamento immagine e dati rispettivamente descritte nella funzione:
// FUNZIONE DI CARICAMENTO FOTO GRANDE E DATI
mc.onPress=function(){
// chiamata
carica_foto(this.img)
carica_dati(this.img, this.cat,this.desc,this.drive,this.dim)
}
dobbiamo necessariamente costruire i clip MainBIG e MainTXT, quindi diciamo brevemente che entrambi sono costruiti su almeno due livelli, uno di sfondo ed uno per la ricezione dei dati (immagini o testi).
Clip MainBIG
Clip MainTXT
Creati questi due clip e posizionati come da figura iniziale, possiamo procedere alla definizione delle due funzioni.
function carica_foto(nome){
MainBIG.IMGBIG.loadMovie("foto/"+nome)
/*
questa parte che segue è opzionale, nel senso che se la foto la si vuol
far apparire nelle sue reali, essendo già caricata nella cache, non è
necessario il controllo del caricamento. Diversamente se si vuole un
dimensionamento adHoc, allora è necessaria.
*/
// Opzione ---------------------------------->
MainBIG.onEnterFrame=function()
{
if(this.IMGBIG.getBytesLoaded()>1024 && this.IMGBIG.getBytesLoaded() == this.IMGBIG.getBytesTotal())
{
// calcolo dimensioni originali
this.larg=this.IMGBIG._width
this.alt=this.IMGBIG._height
// chiamo la funzione di re-dimensionamento
this.IMGBIG._xscale = Math.floor(310/this.larg*100)
this.IMGBIG._yscale = Math.floor(190*100/this.alt*100)
this.IMGBIG._width=310
this.IMGBIG._height=190
this.IMGBIG.onEnterFrame = function(){
// enterFrame per aumentare gradualmente l'alpha dell'immagine caricata
if(this._alpha < 100){this._alpha+=20;}
else {this._alpha = 100; delete this.onEnterFrame;}
}
delete this.onEnterFrame
} // fine IF
} // Fine mc.onEnterFrame=function()
// Fine Opzione ------------------------------->
}
function carica_dati(pic,cat,desc,drive,dim){
MainTXT.txt0=pic
MainTXT.txt1=cat
MainTXT.txt2=desc
MainTXT.txt3=drive
MainTXT.txt4=dim
}
Finalmente è arrivato il momento di verificare il comportamento dei pulsanti "PAG" per lo spostamento del MainMINI e dei pulsantini Avanti e Dietro, per lo scorrimento dei foglietti mascherati. Per provare i pulsantini, senza impazzire nel file TXT inserite:
&Totale=60&
Il risultato che otterrete saranno 10 fogliettini ed avrete la possibilità di scorrere avanti ed indietro la barra di navigazione.
// Protoype per cambio pagine 1 x 6 miniature
MovieClip.prototype.protopag=function(){
this.onPress=function(){
numero=Number(substring(this._name,4,2))
if(numero == 1){ _level0.MainMINI._y=210}
else{_level0.MainMINI._y=(210-(160*numero - 160))}
}
}
I numeri che trovate - non sono altro che le coordinate di posizionamento del MainMINI e le sue dimensioni
Funzione per i pulsanti di navigazione
avanti.onPress=function(){
// attivo i pulsanti solo se la larghezza di MainPag
è superiore alla larghezza della maschera
if(MainPag._width > MaskPag._width){
// calcolo le dimensioni di larghezza dei due clip
L0=MainPag._x+MainPag._width
L1=MaskPag._x+MaskPag._width
// confronto
if(L0>=L1){
// avanzo della larghezza di un foglietto
MainPag._x-=30
}
}
}indietro.onPress=function(){
// Per il pulsante di ritorno è più semplice,
basta confrontare la posizione dei due clip
if(MainPag._x < MaskPag._x){
// avanzo della larghezza di un foglietto
MainPag._x+=30
}
}
Un'ultima attenzione circa l'usabilità delle miniature utilizzate come pulsanti, inserite all'interno di MINI un piccolo clip come il check, abilitatelo in visualizzazione se premuto il pulsante.Quindi riprendete la funzione ed aggiungete la riga in grassetto.
// FUNZIONE DI CARICAMENTO FOTO GRANDE
mc.onPress=function(){
// chiamata
carica_foto(this.img)
carica_dati(this.img, this.cat,this.desc,this.drive,this.dim)
// visitato
this.check_visit._visible=1
}
Non c'è altro, buon lavoro.