Album foto - foto SlideShow
12.11.2008
In acest tutorial vom incerca sa construim doua tipuri de albume fotografice.
5664 afisari 0 Rating (6 voturi) 30 min

În primul exemplu, imaginile vor fi de dimensiuni diferite, vor fi încadrate de un chenar care se va redimensiona la încărcarea fiecărei noi imagini. Imaginile vor fi numerotate (0.jpg, 1.jpg …) pentru o încărcare consecutivă (în exemplul următor imaginile nu trebuie să fie neapărat cu aceste denumiri). După încărcarea în întregime a unei imagini, se vor găsi dimensiunile fotografiei, se va şterge vechea imagine, se va redimensiona chenarul după care va fi afişată noua fotografie.

Vom schimba proprietăţile documentului pentru a avea dimensiunile 800x500 şi o viteză de afişare de 30 de cadre pe secundă (în cazul în care imaginea este mai mare de 800x500 puteţi să realizaţi şi o scalare a acesteia).

In timpul încărcării unei imagini, imaginea precedentă trebuie să fie afişată. Din acest motiv nu trebuie să încărcăm imaginea nouă în acelaşi MovieClip ca şi precedenta – ne vom folosi de două clipuri „m0” şi „m1”.

Chenarul va fi simulat de un dreptunghi ce va fi desenat folosind instrumentele Flash-ului şi care apoi va fi convertit într-un MovieClip cu numele de instanţă „cadru” şi cu punctul de înregistrare în centru. Când construiţi dreptunghiul (a cărui dimensiuni iniţiale nu contează) aveţi grijă ca marginea (conturul) desenului să fie setată ca „hairline” (opţiune disponibilă din fereastra de proprietăţi imediat după selectarea instrumentului recangle). Cu ajutorul ferestrei „Align” (CTRL+K) poziţionaţi dreptunghiul în centrul scenei: apăsaţi butonul „To stage” din dreapta după care apăsaţi al doilea buton de pe primele două rânduri (evident obiectul în formă de dreptunghi trebuie să fie selectat).

La încărcarea unei imagini ne vom folosi de un preloader pentru a comunica vizitatorului cât mai are de aşteptat până la încărcarea următoarei imagini. Din acest motiv vom importa în scriptul nostru clasa grafix.as care are o funcţie ce desenează o bară de progres. Vom face pentru început câteva setări cum ar fi dimensiunile fictive ale unei imagini, numărul imaginii curent afişate precum şi în ce MovieClip (m0 sau m1) este afişată (iniţial nu avem nici o imagine încărcată dar vom face aceste setări – oarecum artificiale – pentru a avea o continuitate în încărcările imaginilor).

#include "grafix.as"
lung = 0;
inalt = 0;
img_nr = 1;
nr_mc = 1;
contor = 0;

Cu funcţiile ce vor afişa bara de progres deja v-aţi obişnuit din excerciţiul cu preloaderul ce putea găsi apariţia unei erori:

var un_obiect:Object = new Object();
un_obiect.onLoadStart = function():Void {
    _root.createEmptyMovieClip("bara_progres", 10000);
};
 
un_obiect.onLoadProgress = function(destinatie:MovieClip, bytesLoaded:Number, bytesTotal:Number):Void {
    _root.bara_progres.desenaza_bara_progres(200, 490, 400, 7, bytesLoaded, bytesTotal);
};
 
un_obiect.onLoadComplete = function():Void {
    _root.bara_progres.unloadMovie();
};

De această dată vom mai adăuga (sau completa funcţiile explicate acolo) cu următoarele:

un_obiect.onLoadInit = function(destinatie:MovieClip):Void{
    _root.contor = 0;
    _root.lung = destinatie._width;
    _root.inalt = destinatie._height;
    _root.m1._alpha = 0;
    _root.m0._alpha = 0;
    _root["m"+nr_mc]._x = (800-lung)/2;
    _root["m"+nr_mc]._y = (500-inalt)/2;
};
 
un_obiect.onLoadError = function(destinatie:MovieClip, httpStatus:Number):Void {
    _root.img_nr++;
    _root.img_nr %= 7;
    _root.monitor.loadClip(_root.img_nr+".jpg", "_root.m"+_root.nr_mc);
    _root.contor = -1;
    _root.bara_progres.unloadMovie();
};

Prima funcţie se va executa imediat după încărcarea completă, mai exact atunci când clip-ul va fi iniţializat (adică imaginea va fi efectiv încărcată în MovieClip-ul în care s-a dat comanda de încărcare). În această funcţie vom reiniţializa un contor care are rolul de a cronometra timpul pentru care imaginea a stat în scenă – după un timp vom încărca următoarea imagine, vom reface variabilele ce reprezintă lungimea şi înălţimea imaginii încărcate pentru a putea redimensiona dreptunghiul care joacă rol de chenar; ambele MovieClip-uri vor avea factorul de opacitate setat la 0 (complet transparente) şi va fi repoziţionată imaginea nou încărcată pentru a fi în centrul scenei (deşi invizibilă).

În cazul întâlnirii unei erori (eveniment captat prin intermediul funcţiei onLoadError), vom încerca să încărcăm următoarea imagine. Împărţirea modulo 7 efectuată imediat după încrementarea numărului imaginii are rolul de a cicla cele 7 imagini de tip jpg numerotate de la 0 la 6. În momentul iniţializării unei noi încărcări, contorul este setat la o valoare foarte mică pentru a împiedica încărcarea altei imagini (am văzut că atunci când imaginea este încărcată complet, contorul este resetat la 0; de fapt de fiecare dată când acest contor va depăşi valoarea 200 se va începe încărcarea unei noi imagini; nu vrem să începem încărcarea unei imagini în timpul încărcării precedentei şi din acest motiv iniţializăm contorul cu un număr negativ şi-l vom incrementa doar dacă este 0 sau mai mare).

În continuare vom crea cele două MovieClip-uri şi vom începe încărcarea primei imagini (din ce motiv construim un obiect de tip MovieClipLoader şi cum îl folosim nu mai explicăm deoarece acest subiect a fost deja atins la un exerciţiu anterior):

var monitor:MovieClipLoader = new MovieClipLoader();
monitor.addListener(un_obiect);
_root.createEmptyMovieClip("m0", 0);
_root.createEmptyMovieClip("m1", 1);
monitor.loadClip("1.jpg", "m1");

Pentru redimensionarea chenarului sau pentru afişarea progresivă (transparent spre opac) a imaginilor, trebuie să avem o funcţie care să se repete încontinuu. _root.onEnterFrame este exact ceea ce avem nevoie:

_root.onEnterFrame = function() {
if (_root.contor>=0) {
    _root.contor++;
}
if (_root.contor>200) {
    _root.img_nr++;
    _root.img_nr %= 7;
    _root.nr_mc++;
    _root.nr_mc %= 2;
    _root.monitor.loadClip(_root.img_nr+".jpg", "_root.m"+_root.nr_mc);
    _root.contor = -1;
}
_root.cadru._height = _root.cadru._height - (_root.cadru._height-_root.inalt-5)/9;
_root.cadru._width = _root.cadru._width - (_root.cadru._width-_root.lung-5)/9;
 
if (Math.abs(_root.cadru._width-_root.lung)<10) {
    _root["m"+nr_mc]._alpha += 4;
}
};

Aşa cum am promis vom incrementa contorul doar dacă acesta este pozitiv, dacă depăşeşte valoarea 200 vom trece la următoarea imagine, vom schimba MovieClip-ul în care încărcăm imaginea, vom porni încărcarea imaginii noi, vom seta contorul la -1 (din acelaşi motiv ca şi prima dată).

În continuare în mod continuu (deşi nu neapărat necesar) vom modifica dimensiunea chenarului pentru a fi cu două unităţi mai mare decât imaginea încărcată (valoarea -5 lasă două unităţi în stânga şi două în dreapta). Dacă dimensiunea chenarului este aproape de cea dorită începem să creştem gradul de opacitate al MovieClip-ului pentru a face vizibilă imaginea.

Testaţi exemplul apăsând de două ori CTRL+Enter (pentru a observa şi preloaderul). Acest exemplu a fost realizat pentru 7 imagini: de la 0.jpg până la 6.jpg. Ce se întâmplă dacă una din cele 7 imagini lipseşte ? Va mai funcţiona corect exemplul ? (încercaţi să răspundeţi înainte de a şterge una din imagini). Din ce motiv atunci când expiră contorul schimbăm şi MovieClip-ul în care încărcăm următoarea imagine dar nu facem acest lucru şi atunci când se produce o eroare (atunci schimbam doar imaginea ce trebuie încărcată)?

Ca exerciţiu încercaţi să realizaţi acelaşi exemplu fără a desena chenarul folosind instrumentele Flash-ului, adică creaţi acest chenar (împreună cu animaţia sa) numai folosind ActionScript.

Cel de-al doilea album fotografic va încărca o fotografie numai când se va face cererea de încărcare. Iniţial vizitatorului paginii i se va afişa o listă cu imaginile disponibile (în format thumb-nail9), încărcarea efectuându-se numai atunci când acesta va apăsa pe imaginea dorită. Fiecare imagine mică din listă se va încărca folosind un preloader dar nu pentru a afişa cât mai avem de aşteptat până la final ci pentru a şti momentul în care încărcarea este completă. Pentru a forma o listă vom ataşa fiecare imagine încărcată unui MovieClip pe care-l vom putea muta sub o mască. In acest fel vom afişa doar o porţiune din el. Lista va fi afişată deasupra locului în care se va încărca imaginea şi din acest motiv pozele din listă vor fi afişate pe orizontală.

Pentru fiecare imagine folosită trebuie să avem stocate (pe server) două imagini: una mică (imaginea ce se va încărca iniţial în listă) şi un a mare (imaginea care se va încărca atunci când imaginea mică va fi apăsată).

Numele fişierelor nu vor mai fi sub formă de numere (de fapt prima metodă era una destul de artificială), ele vor fi încărcate dintr-un fişier XML ce conţine numele tuturor imaginilor.

Fişierul XML conţine doar date structurate. Un fişier în format XML care va indica Flash-ului că are de afişat 3 imagini în format JPG va avea următoarea structură (imagini.xml):

<?xml version="1.0" ?>
<imagini>
    <img fisier="gradina.jpg" descriere="Gradina din spatele casei" data="10.02.2006" />
    <img fisier="apa_curgatoare.jpg" descriere="Bistrita iarna" data="01.02.2006" />
    <img fisier="pisica.jpg" descriere="Persana" data="15.07.2004" />
</imagini>

Fiecare imagine este identificată printr-un nouă intrare de tip img. Singura informaţie disponibilă (pentru început) pentru fiecare imagine este numele fişierului ce va fi încărcat.

Scrieţi un fişier XML cu un conţinut asemănător cu cel dat mai sus particularizat pentru imaginile pe care doriţi să le folosiţi. Denumiti acest fişier „imagini.xml”. În directorul în care este situat acest fişier veţi salva şi proiectul flash. În plus, în acelaşi director, veţi adăuga un director „foto” în care veţi pune toate imaginile ce au fost trecute în XMLul construit.

Acest exemplu va fi folosit în crearea paginii personale de web în care toate filmele Flash ce vor fi încărcate la un moment dat ar fi bine să aibă o aceeaşi dimensiune. Deoarece dimensiunea scenei pentru majoritatea aplicaţiilor realizate era de 640x480 şi pentru că vom dori să includem şi această aplicaţie în pagina noastră, dimensiunea scenei va fi setată tot la această rezoluţie. Pozele care se vor încărca nu trebuie să fie de dimensiuni foarte mari, personal în pagina web nu pun imagini cu rezoluţie mai mare de 320x240. Pentru fiecare imagine cu rezoluţia 320x240 veţi avea nevoie de incă una cu dimensiunea 96x72 (poza redimensionată). Numele imaginii mici va fi acelaşi cu numele imaginii mari dar va avea prefixul „mic_” (De exemplu, imaginea mică pentru „gradina.jpg” se va numi „mic_gradina.jpg”). Imaginile mici vor fi puse în acelaşi director cu cele mari.

Scriptul va fi aşezat în totalitate în primul cadrul al al timeline-ului. Pentru început va trebui să definim un obicet XML şi să încărcăm lista imaginilor.

Deocamdata vom vedea o eventuală problemă şi cum ar putea fi evitată: după ce vom termina de încărcat fişierul XML în Flash, îl vom procesa şi vom începe încărcarea fişierelor (mici) de pe server pentru a construi lista cu fişierele disponibile. Pentru fiecare imagine mică vom avea nevoie de câte un MovieClip nou şi pentru fiecare MovieClip nou va trebui să executăm comanda loadMovie pentru a încărca imaginea externă.

Dacă sunt puţine imagini, nu există nici o problemă dar în cazul în care avem un număr mare de imagini, acestea îşi vor începe încărcarea aproape toate simultan şi se vor „îngreuna” una pe celaltă (de fapt probabil cu toţii aţi observat că atunci când încercaţi sa copiaţi mai multe fişiere de pe o partiţie pe alta este mai avantajos să le copiaţi pe rând decât simultan). Pentru început vom scrie scriptul care va încărca toate imaginile (mici) simultan (desi gresit, el are o anumită importanţă în observarea funcţionării şi poate fi completat cu uşurinţă pentru a fi schimbat în versiunea corectă):

var imagini = new XML();
imagini.ignoreWhite = true;
imagini.onLoad = function() {
    _root.nr_max_img = _root.imagini.firstChild.childNodes.length;
    trace("numarul de poze:"+_root.nr_max_img);
    _root.createEmptyMovieClip("lista_imagini", 0);
    for (i=0; i<_root.nr_max_img; i++) {
        _root.lista_imagini.createEmptyMovieClip("img"+i, i);
        _root.lista_imagini["img"+i].loadMovie("foto/mic_"+_root.imagini.firstChild.childNodes[i].attributes.fisier);
    }
};
imagini.load("imagini.xml");

Scriptul funcţionează în felul următor: crează un obiect XML, ignoră spaţiile albe (am amintit într-un capitol anterior că acestea împiedică buna procesare a documentului XML), este creată funcţia ce se va executa în momentul încărcării XMLului (onLoad) şi se porneşte încărcarea XML-ului „imagini.xml” ce conţine lista fişierelor. Câteva comentarii asupra funcţiei onLoad: după încărcarea XML-ului memorăm numărul de poze în variabila _root.nr_max_img şi afişăm acest număr de poze prin intermediul comenzii trace (aceasta este mai mult o verificare că XMLul s-a încărcat corect). În continuare vom crea un MovieClip cu numele de instanţă „lista_imagini” în care se vor încărca pe rând imaginile desemnate de XML, fiecare în propriul MovieClip.

Astfel, pentru fiecare imagine (for-ul de fapt merge de la valoarea 0 până la numărul maxim de imagini deci vom putea prelua pe rând imaginile) vom crea câte un MovieClip nu numele de instanţă „img”+i (de fapt vom avea img0, img1, img2,....) şi fiecărei instanţe îi vom permite încărcarea prin intermediul loadMovie a imaginii asociate.

Problema care apare cu scenariul acesta este încărcarea simultană a mai multor fişiere (acest fapt este rezultatul executării foarte rapide a buclei „for”). În final, dacă în faza de test veţi selecta „Bandwith Profiler” din meniul „View” şi veţi apăsa de două ori CTRL+Enter (reamintesc că acest lucru simulează încărcarea pentru un anumit tip de bandă) veţi avea un rezultat ca în imaginea de mai jos.


Aşa cum am zis, încărcarea de acest tip constituie o problemă atunci când numărul fişierelor este mare. În acest caz, pentru a evita „aglomerarea” ar trebui să nu permitem Flash-ului să încarce altă imagine decât dacă cea anterioară a fost încărcată cu succes (sau dacă imaginea nu se găseşte pe server.

Pentru a determina momentul încărcării complete a unei imagini vom apela la un „listener” asemănător cu cel făcut în cadrul preloaderelor dar de această dată nu va avea nevoie de desenarea unei bare de progres ci doar de tratarea evenimentelor onLoadComplete şi eventual a lui onLoadError (pentru a putea trece la următoarea imagine ce trebuie încărcată dacă cea curentă nu a fost găsită pe server).

În scriptul ce va încarca imaginile prin intermediul listenerului trebuie să avem grijă ca dacă imaginea nu este găsită pe server (sau apare o eroare de încărcare) să nu creăm un nou MovieClip pentru încărcarea imaginii următoare (de fapt o altă soluţie ar putea fi ca în tratarea evenimentului onLoadError să distrugem MovieClip-up ce a cauzat eroarea). Din acest motiv vom folosi două contoare, unul pentru a reţine la al câtelea MovieClip am ajuns (variabila i) şi al doilea pentru a şi care este imaginea ce va fi încărcată (variabila j).

Un alt aspect este modul în care încărcăm imaginile. În cadrul funcţiei _root.OnEnterFrame vom testa în mod continuu dacă putem încărca o următoare imagine (prin testarea unei variabile care va avea valoarea false pe durata încărcării unei imagini) şi numai în cazul în care aceasta este adevărată (se va face true doar la apariţia evenimentului onLoadComplete) înseamnă că momentan nu se încarcă nimic şi vom putea încărca următoarea imagine.

Scriptul este următorul:

var imagini = new XML();
imagini.ignoreWhite = true;
imagini.onLoad = function() {
    
    // cream un listener:
    var un_obiect:Object = new Object();
    un_obiect.onLoadComplete = function():Void {
        _root.lista_imagini["img"+mc_curent].nr_imagine = img_curent;
        _root.poti_incarca_urmatoarea = true;
    };
    un_obiect.onLoadError = function(destinatie:MovieClip, httpStatus:Number):Void {
        _root.poti_incarca_urmatoarea = true;
        _root.eroare_de_incarcare = true;
    };
    var monitor:MovieClipLoader = new MovieClipLoader();
    monitor.addListener(un_obiect);
    
    // am terminat de creat listenerul
    _root.nr_max_img = _root.imagini.firstChild.childNodes.length;
    trace("numarul de poze:"+_root.nr_max_img);
    _root.createEmptyMovieClip("lista_imagini", 0);
    _root.poti_incarca_urmatoarea = true;
    _root.eroare_de_incarcare = false;
    
    i = 0;
    j = 0;
    _root.onEnterFrame = function() {
        if ((_root.poti_incarca_urmatoarea) && (j<_root.nr_max_img)) {
            _root.poti_incarca_urmatoarea = false;
            if (!_root.eroare_de_incarcare) {
                _root.lista_imagini.createEmptyMovieClip("img"+i, i);
            } else {
                i--;
                _root.eroare_de_incarcare = false;
            }
            _root.lista_imagini["img"+i]._x = i*100;
            _root.mc_curent = i;
            _root.img_curent = j;
            monitor.loadClip("foto/mic_"+_root.imagini.firstChild.childNodes[j].attributes.fisier,_root.lista_imagini["img"+i]);
            i++;
            j++;
        }
        
        if ((j==_root.nr_max_img) && (_root.poti_incarca_urmatoarea)){
            nr_total_mc = i;
            for (i=0; i<nr_total_mc; i++) {
                _root.lista_imagini["img"+i].onPress = function() {
                    incarca_imagine_mare("foto/"+_root.imagini.firstChild.childNodes[this.nr_imagine].attributes.fisier);
                };
            }
            _root.onEnterFrame = null;
        }
    };
};
imagini.load("imagini.xml");
Copyright © 2008-2010 E-LEARN.ro. Toate drepturile rezervate. Conceput si realizat de Neokinetics Software.