Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

XML : chargement d'une liste d'images (3)

Compatible ActionScript 1 et 2. Utilise des techniques dépréciées. Cliquer pour en savoir plus sur les compatibilités.

Article écrit le 15/01/2004 18.12 Par chipaldance.

Avertissement:
Avant de lire ce tutorial, il est conseillé de lire les précédents (ceux portant sur la gestion d'une galerie d'images);
En particulier, les images ne doivent PAS etre enregistrées en mode progressif, flash n'accpte pas cela.
Ceci dit, attaquons les choses sérieuses:

Ce tutorial fournit 4 méthodes pour l'objet MovieClip, ce qu'on appelle 'prototype' par abus de langage, qui constituent du code polyvalent et réutilisable.
Il convient de placer ces scripts dans 4 fichiers texte séparés que vous appelerez depuis flash au moyen de la commande #include , de cette façon:

#include "monFichierTexte.txt"

Il ne faut pas mettre de point-virgule à la fin de la ligne !

Voici donc le code que vous aurez à taper dans les actions de votre animation, sous flash:

#include "traceRectangle.txt"
 
#include "setPreloader.txt"
 
#include "loadFile.txt"
 
#include "loadGalerie.txt"
 
_root.createEmptyMovieClip("galerie,1");/*clip pour les miniatures*/
_root.createEmptyMovieClip("bigPhoto,2");/*pour afficher la grande image*/
_root.galerie._x=10;/*decaler la galerie de 10 px vers la gauche*/
_root.galerie._y=10;
_root.bigPhoto._x=10;
_root.bigPhoto._y=100;/*en effet la galerie fait déjà 80 px de haut*/
_root.galerie.loadGalerieFromXml("data.xml",80,10,"lignes",1,_root.bigPhoto);
stop()

(ceci constitue tout le code à taper dans flash, sur les actions de la première image.)

A signaler:
La construction de la galerie de miniatures ne change pas, il s'agit du meme prototype que précédemment, à part la ligne pour rendre cliquable les vignettes; Si vous n'avez pas saisi quelque chose, reportez-vous aux tutoriaux précédents, où le problème est plus développé.

Une fois que la galerie d'images a été construite, on se retrouve avec plusieurs clips (les miniatures) que l'on veut rendre clicables.
On fait alors:

clip.onRelease=function(){ /* les actions */}

Comme on manque de place, on aimerait bien regrouper toutes les actions en une seule, donc on utilise une nouvelle fonction:

MovieClip.loadFile(image_ou_swf);

Cette fonction devra charger l'image ou l'animation, et aussi construire une barre de loading pour visualiser la progression du chargement de l'image.

Il s'agit donc d'un problème de préchargement. Maintenant, pour éviter de trop compliquer, prenons le problème à l'envers:
–>Qui dit miniatures cliquables, dit ensuite images à charger.
–>Qui dit images à charger dit barre de chargement.
–>Qui dit barre de chargement dit… barre.

Il nous faut donc tout d'abord un script pour dessiner un rectangle:

fonction traceRectangle:

MovieClip.prototype.traceRectangle=function(xPos,yPos,width,height,fillColor,lineColor,alpha){
 
  this.beginFill(fillColor,alpha); /* debut du remplissage */
 
  this.lineStyle(1,lineColor,alpha); /* début du contour */
 
  this.moveTo(xPos,yPos);
 
  this.lineTo(xPos+width,yPos);
 
  this.lineTo(xPos+width,yPos+height);
 
  this.lineTo(xPos,yPos+height);
 
  this.lineTo(xPos,yPos); /* fin du contour */
 
  this.endFill(); /* fin du remplissage */
 
}

Ca va jusqu'ici ?
Vous retrouverez ce code dans le zip fourni, c'est dans 'traceRectangle.txt'.

Maintenant que l'on sait tracer un rectangle dynamiquement, voyons le loading proprement dit:
Vous devriez à avoir l'habitude tellement il y a de posts et de tutoriaux dessus wink.gif Vous avez quand meme ici une n-ième version d'un préchargement, qui utilise notre script précédent, pour dessiner la barre de chargement:

fonction setPreloader:

MovieClip.prototype.setPreloader=function(clip){
 
  /* options à modifier */
 
  infos={x:0,y:-15,width:100,height:10,fillColor:0xeeeeee,lineColor:0x000000,alpha:100,message:" loading..."};
 
  /* on décale le preloader */
 
  this._x=clip._x+infos.x;
 
  this._y=clip._y+infos.y
 
  /* on crée un clip pour la barre de loading */
 
  this.createEmptyMovieClip("barre",1);
 
  this.createTextField("message",2,infos.width,-5,100,20);
 
  this.message.text=infos.message; /* on écrit le message d'attente */
 
  this.onEnterFrame = function() {
 
     /* la boucle pour la progression du loading */
 
     this.barre.clear();
 
     /* on trace le rectangle dans la barre: */
 
     this.barre.traceRectangle(0,0,infos.width*this.barre.percent,infos.height,infos.fillColor,infos.lineColor,infos.alpha);
 
     /*  on calcule l'avancement du loading: */
 
     this.barre.percent=clip.getBytesLoaded()/clip.getBytesTotal();
 
     if (this.barre.percent>=0.99) { /* si c'est (presque) fini: */
 
        clip.onRelease=function(){ clip.removeMovieClip();}
 
        this.removeMovieClip(); /* on enleve la barre de chargement */
 
     }
 
  }
 
}

Voyons comment fonctionne ce code, c'est un peu inhabituel.
Ce code transforme un clip quelquonque en un module de préchargement d'un clip cible, un 'preloader'.
Il y aura donc deux clips: celui où on charge l'image, et celui qui s'occupe de surveiller le chargement, le preloader.

Pour charger une image, il faudra donc quatre étapes:
–>creer un clip vide pour l'image.
–>creer un deuxième clip vide (pour le preloader).
–>lancer le chargement de l'image dans le clip 1.
–>dire au clip 2 de s'occuper du préchargement, ce qui se fera par: [as]clip2.setPreloader(clip1)</code> On a décidé de regrouper ces quatres étapes dans une nouvelle fonction:

fonction loadFile:

MovieClip.prototype.loadFile=function(file){
 
  this.createEmptyMovieClip("pic", 102); /* le clip pour l'image ou le swf */
 
  this.createEmptyMovieClip("control",103); /* le clip por le preload */
 
  this.pic.loadMovie(file); /* on lance */
 
  this.control.setPreloader(this.pic); /* et on attache le preloader */
 
}

Quand on cliquera sur une vignette, l'action à executer est:

clipCible.loadFile(url_image);

C'est pratiquement la seule ligne qui change par rapport à l'ancien script, je remets la fonction ici pour ne pas vous forcer à faire de pénibles va-et-vient entre posts dans le forum:

Finalement:

MovieClip.prototype.loadGalerieFromXml = function(file,zoneTaille,zoneEspace,affichage,nombre,clipCible){
 
  this.galerieXml = new XML();
 
  racine=this;
 
  this.galerieXml.ignoreWhite = true;
 
  this.galerieXml.onLoad = function(){
 
     racine.zoneTaille = zoneTaille;
 
     racine.zoneEspace = zoneEspace;
 
     racine.picsLoaded = true;
 
     racine.affichage = affichage;
 
     racine["nb"+affichage] = nombre;
 
     racine.galeriev = this.firstChild.childNodes;
 
     racine.lon = racine.galeriev.length;
 
     for (var i = 0; i<racine.lon; i++) {
 
        var nom = racine.galeriev[i].attributes.small;    
 
        racine.createEmptyMovieClip("bitmap_mc"+i, i+10);
 
        racine["bitmap_mc"+i].loadMovie(nom);
 
     }
 
     racine.onEnterFrame=function(){
 
        this.picsLoaded=true;
 
        for (var i = 0; i<this.lon; i++){
 
            racine["bitmap_mc"+i]._visible=false;
 
           if(this["bitmap_mc"+i].getBytesLoaded() !=this["bitmap_mc"+i].getBytesTotal()||this["bitmap_mc"+i].getBytesLoaded()==0)
 
           {this.picsLoaded=false;break;}}
 
        if(this.picsLoaded==true){
 
           delete  this.onEnterFrame;
 
           this.a = 0;  
 
           this.b = 0;  
 
           for (var i=0; i<this.lon; i++) {
 
              racine["bitmap_mc"+i]._visible=true;
 
              if (this.a == this["nb"+this.affichage]) {
 
                 this.a = 0;
 
                 this.b++;
 
              }
 
              this["bitmap_mc"+i]._x =(this.affichage=="Colonnes"? this.a : this.b)*(this.zoneTaille+this.zoneEspace);
 
              this["bitmap_mc"+i]._y =(this.affichage=="Colonnes"? this.b : this.a)*(this.zoneTaille+this.zoneEspace);
 
              this.a++;
 
              this["bitmap_mc"+i].big=this.galeriev[i].attributes.big;
 
           }
 
           for (var i = 0; i<this.lon; i++) {
 
 
 
              this.facteur=Math.max(this["bitmap_mc"+i]._width,this["bitmap_mc"+i]._height)/this.zoneTaille;  
 
              this["bitmap_mc"+i]._xscale = this["bitmap_mc"+i]._yscale /=this.facteur;
 
              this["bitmap_mc"+i].onRelease= function(){ clipCible.loadFile(this.big); }
 
           }
 
        }
 
     }
 
  }
 
  this.galerieXml.load(file);
 
}

P.S : vous devez bien sur placer vos images dans le repertoire, et modifier le fichier XML en conséquence, et il faudra prévoir des miniatures de vos imges, la taille importe peu, pareil pour les proportions, ce qui compte, c'est que le poids de ces images soit vraiment faible, bien sur.
voici les fichiers zippés

Merci à Damien pour ce tutorial.