Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Diaporama pas à pas - 5 - Les barres de progression du téléchargement - 2 - onLoadStart et onLoadProgress

Compatible ActionScript 2. Cliquer pour en savoir plus sur les compatibilités.Par lilive (Olivier Tarasse), le 24 juin 2008
  • Révision : lilive - 10/09/2008

Objectif

Voici le deuxième volet de la cinquième partie de la série de tutoriaux commencée ici.

Nous avons maintenant le bagage graphique nécessaire pour dessiner les barres de progression du téléchargement, et c'est ce que nous allons faire.

A la fin de cette page nous auront réalisé ceci:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.


Préambule

Pour l'instant, nous n'avons pas encore parlé de la “mise en ligne” du diaporama. C'est le moment.

Par “mise en ligne”, j'entends placer le fichier swf et les images sur un serveur, de manière à ce qu'une autre personne que vous puisse consulter le diaporama avec son navigateur internet habituel.

Si jusque-là vous vous en êtes tenus à tester le swf “en local”, c'est-à-dire en chargeant le swf et les images depuis votre disque dur, les temps de chargements passaient inaperçus, car trop rapides. Pour suivre le présent article, il va falloir mettre tout cela en ligne.

Pour les utilisateurs de Flash IDE, il y a une autre solution pour tester les téléchargements sans mettre en ligne. Vous pouvez continuer à tester le diaporama dans l'IDE en simulant le téléchargement. Voyez Aide de Flash > Utilisation de flash > Meilleures pratiques > Optimisation des fichiers Flash pour une sortie SWF.

La mise en ligne dépasse le cadre de la programmation et du présent tutoriel. C'est pour cela que vous devez vous assurer d'avoir les:


Connaissances requises pour cette partie

Il vous faut savoir mettre le diaporama en ligne. C'est-à-dire:

  • Créer la page html qui affiche le swf. Documentation à ce sujet:
    • L'IDE de flash peut le faire automatiquement. Voir Aide de Flash > Utilisation de Flash > Publication du contenu Flash > Utilisation de Flash Player > Définition de paramètres de publication en vue de créer des documents HTML dotés d'un contenu Flash incorporé.
    • Les articles du wiki traitants de publication.
  • Une fois que vous avez le html en plus du swf et des images, il faut envoyer tout cela sur le net. Vous devez avoir une solution d'hébergement, par exemple les “pages persos” que proposent la plupart des fournisseurs d'accès à internet sans coût supplémentaire à son abonnement. Pour transférer les fichiers de votre disque dur vers l'hébergeur vous pouvez utiliser un programme tel que Filezilla. Quelques documents:
  • Et pour finir, vous devez bien sûr savoir indiquer à votre navigateur internet l'url du résultat, pour charger le html qui va afficher le swf.


Comment suivre cet article

1- Petit code deviendra grand

Notre code commence à devenir long, et cela alourdirait l'article de le rappeler intégralement à chaque changement. A partir de maintenant, je ferais apparaître dans le corps de l'article uniquement les changements. Bien sûr vous trouverez le code complet en pièce jointe: 1)

2- Une fois n'est pas coutume, faisons lent et lourd

Vous pouvez continuer à tester le swf en local, mais pour mieux apprécier la fonctionnalité des barres de progression, vous aurez intérêt à le mettre en ligne. Vous devez donc transférer chez votre hébergeur le html, le swf et le dossier images contenant les images.

N'utilisez plus les images que je fournissais jusque-là en pièce jointe, car elles sont si légères que le téléchargement sera trop rapide pour bien voir le résultat. Utilisez plutôt vos propres images, peu compressées.

Vous pouvez même, pour les alourdir encore, utiliser des images d'une dimension en pixel beaucoup plus grandes que le diaporama lui-même. Nous les redimensionnerons au moment de leur affichage. Ce qui compte, c'est qu'elles soient toujours au format 4:3 .

Si votre connexion est rapide, n'hésitez pas à utiliser des images de plusieurs centaines de kilo-octets.

Avant d'aller plus loin dans la lecture, mettez le diaporama en ligne et testez-le. L'idéal serait qu'il y ait un temps de téléchargement de quelques secondes entre le moment où vous cliquez sur le bouton “image suivante” et le moment où l'image apparaît.

Quand vous aurez visionné les images une première fois, vous constaterez que le temps de téléchargement diminue énormément. Ceci est du à la “mise en cache” par le navigateur, c'est-à-dire que pour accélérer la navigation, les derniers fichiers chargés sont automatiquement et temporairement copiés sur votre disque dur. Si lors de vos essais vous souhaitez retrouver le temps de téléchargement initial, vous pouvez faire l'opération appellée “vider le cache” de votre navigateur. Si vous ne savez pas le faire, consultez l'aide de votre navigateur, ou faites une recherche sur internet avec les mots ”vider cache navigateur” en remplaçant navigateur par le nom du votre.

Une autre solution pour faire les tests, pour ceux qui utilisent Flash IDE, est de tester le programme en utilisant la possibilité de simuler le téléchargement. Pour cela il faut tester l'animation comme d'habitude (Ctrl + Entrée) puis basculer vers la simulation du téléchargement, en choisissant Simuler le téléchargement dans le menu Affichage (ou appuyer une deuxième fois sur Ctrl + Entrée). Notez que cette façon de faire ne simule pas la mise en cache des images par le navigateur, ce qui posera problème au chapitre V si vous l'utilisez.


I - Redimensionner les images

La zone d'affichage sur la scène fait 400×300 pixels. Disons que vous utilisez maintenant des images d'une taille supérieure. Il va falloir les redimensionner à cette taille pour les afficher correctement.

Flash offre la possibilité de modifier très simplement la taille d'un MovieClip. Il suffit de donner aux propriétés _width (largeur) et _height (hauteur) les valeurs que l'on souhaite. Par exemple:

unClip._width = 400;
unClip._height = 300;

va redimensionner le MovieClip unClip aux dimensions 400×300 pixels.

Je vous rappelle que dans notre diaporama, nous chargeons l'image dans le MovieClip imageChargementMC avec la méthode loadClip d'un MovieClipLoader. Ainsi:

mcl.loadClip("images/image" + imageActuelle + ".jpg", imageChargementMC);

Il va falloir opérer le redimensionnement de imageChargementMC une fois que l'image est chargée. Ce serait une mauvaise idée (et un problème que l'on voit revenir fréquemment sur le forum) de le faire avant que le chargement soit terminé, comme cela:

imageChargementMC._width = 400;
imageChargementMC._height = 300;
mcl.loadClip("images/image" + imageActuelle + ".jpg", imageChargementMC);

Car lors du chargement, le MovieClip est détruit, puis recréé. La plupart des propriétés du MovieClip sont alors perdues, à l'exception par exemple de _x et _y. Nous allons donc attendre la fin du chargement, et effectuer le redimensionnement dans le onLoadInit:

mclListener.onLoadInit = function () {
	imageChargementMC._width = 400;
	imageChargementMC._height = 300;
	imageChargementMC._alpha = 100;
	imageCouranteMC.onEnterFrame = transition;	
}

Remplacez la fonction onLoadInit que nous avions en fin de quatrième partie par celle-ci. Exécutez, le résultat devrait être identique à ce que nous avions déjà:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.
Code complet en pièce jointe: 2)


II - Préparer la barre de progression du téléchargement

1- Un MovieClip dédié à la barre de progression

Pour dessiner la barre de progression, nous allons créer un nouveau MovieClip, par dessus imageChargementMC et imageCouranteMC:

var progressMC:MovieClip = this.createEmptyMovieClip("progress",this.getNextHighestDepth());
progressMC._visible = false;

Comme nous ne désirons faire apparaître ce MovieClip qu'en cas de téléchargement, nous définissons sa propriété _visible comme étant false (faux).

Si vous lisez l'Aide de Flash > Référence du langage ActionScript 2.0 > Classes ActionScript > MovieClip > _visible, vous saurez que cette propriété est de type Boolean (booléen), peut donc recevoir uniquement l'une des deux valeurs true (vrai) ou false (faux), et contrôle la visibilité du clip. Quand _visible=true on voit le MovieClip, quand _visible=false on ne le voit pas.

2- Le message

Nous voulons faire apparaître le message “Chargement en cours…” en cas de téléchargement. Nous avons donc besoin d'un TextField. Nous allons le placer en profondeur 0 dans progressMC, aux coordonnées (120,100), et y écrire le message en blanc.

var progressTF:TextField = progressMC.createTextField("text", 0, 100, 120, 200, 20);
progressTF.textColor = 0xffffff;
progressTF.autoSize = "left";
progressTF.text = "Chargement en cours ...";

Comme progressMC, MovieClip conteneur de progressTF, n'est pas visible, le texte ne sera pas visible non plus pour l'instant.


III - Initialiser la barre de progression au début du téléchargement

1- Faire apparaître le message

Quand un téléchargement débute, nous allons afficher progressMC, en codant:

progressMC._visible = true;

Ce qui fera apparaître tout le contenu de progressMC, c'est-à-dire, pour l'instant, le message. La question est: Où mettre ce code pour qu'il soit exécuté au début du téléchargement? En farfouillant l'Aide de Flash > Référence du langage ActionScript 2.0 > Classes ActionScript > MovieClipLoader, vous devriez trouver notre bonheur. Je vous laisse faire…

…ça y est, vous l'avez?

Et bien oui, il s'agit de l'évènement onLoadStart:

mclListener.onLoadStart = function () {
	progressMC._visible = true;
}

Et puis nous allons faire disparaître le message quand le téléchargement est terminé et que l'image s'affiche:

mclListener.onLoadInit = function () {
	progressMC._visible = false;
	imageChargementMC._width = 400;
	imageChargementMC._height = 300;
	imageChargementMC._alpha = 100;
	imageChargementMC.onEnterFrame = transition;	
}

Compilez le swf, exécutez-le. Pendant chaque chargement, le message apparaît en blanc par dessus l'image déjà affichée. Si vous testez en local vous ne verrez sûrement rien, le chargement ira trop vite. Il faut donc mettre ce swf en ligne. Faites-le, testez de nouveau. Cette fois vous devriez avoir un résultat qui ressemble à:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.
Code complet en pièce jointe 3)

2- Initialiser le dessin de la barre

Comme sur l'exemple en haut de la page, nous voulons dessiner la barre de progression dans un rectangle qui se remplira progressivement. Au lancement du chargement, nous allons dessiner le contour du rectangle en blanc, en utilisant la fonction drawRectangle de la page précédente.

Copiez le code de cette fonction dans celui du diaporama, puis transformez ainsi la fonction onLoadStart:

mclListener.onLoadStart = function () {
	drawRectangle(progressMC, 100, 140, 200, 15, 2, 0xffffff, 100);
	progressMC._visible = true;
}

Pour que le message et la barre, qui sont blancs, soient visibles même sur des images très claires, nous allons leur ajouter un fond noir semi-transparent, en utilisant la fonction drawFilledRectangle de la page précédente.

Copiez cette fonction dans le code du diaporama puis ajoutez à onLoadStart:

mclListener.onLoadStart = function () {
	drawFilledRectangle(progressMC, 0, 0, 400, 300, 0, 50);
	drawRectangle(progressMC, 100, 140, 200, 15, 2, 0xffffff, 100);
	progressMC._visible = true;
}

Dernier point: A chaque fois qu'un téléchargement commence, il faut effacer la barre qui avait pu être dessinée lors du chargement précédent. Pour cela on utilise la méthode clear des MovieClip:

mclListener.onLoadStart = function () {
	progressMC.clear();
	drawFilledRectangle(progressMC, 0, 0, 400, 300, 0, 50);
	drawRectangle(progressMC, 100, 140, 200, 15, 2, 0xffffff, 100);
	progressMC._visible = true;
}

Voyons ce que cela donne:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.
Code complet en pièce jointe: 4)

N'oubliez pas, à chaque fois que vous compilez le nouveau swf, de bien le transférer sur le serveur avant de recharger la page html dans le navigateur. C'est une erreur qui arrive parfois, et qui laisse perplexe à se demander: “Mais pourquoi diable cela ne marche-t-il pas?”


IV - Faire progresser la barre

Maintenant nous allons nous occuper de remplir progressivement la barre au fur et à mesure du téléchargement.

1- Calculer la taille de la barre

Question: Si l'image fait 500 kilo-octets, si 200ko sont déjà chargés, et que je veux dessiner un rectangle plein qui remplisse la barre de progression de blanc dans la même proportion, pour obtenir ceci:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Comment dois-je m'y prendre pour calculer la longueur du rectangle de remplissage?

Tiens! Un peu de mathématiques… :-D
Pour ceux qui n'en ont pas fait depuis longtemps, cela mérite une petite explication:

Si on divise 200 par 500, on obtient 0.4

Pour simplifier, imaginons que la barre de progression entière fasse 1 pixel de large (ce qui n'est pas réaliste, sinon on ne verrait rien). Il faudrait alors la remplir par un rectangle de 0.4 pixels de large, pour rendre compte de la progression du téléchargement à ce moment.

Mais notre barre de progression fait 200 pixels de large.
C'est-à-dire 200 fois plus. Il faut donc que le remplissage soit lui aussi 200 fois plus large, donc d'une largeur de 0.4*200 pixels, soit 80 pixels.

Au final, la largeur du rectangle de remplissage se calcule par (200/500)*200.

Dans un cas plus général, si l'image fait totalBytes octets, et que loadedBytes octets sont déjà chargés, la largeur du remplissage se calcule par (loadedBytes/totalBytes)*200.

2- Actualiser l'affichage de la barre de progression

Nous avons donc besoin d'exécuter du code à intervalles réguliers, tout au long du téléchargement, et de récupérer les valeurs de totalBytes et loadedBytes pour mettre à jour la largeur du remplissage.

Les concepteurs de la classe MovieClipLoader y ont pensé, et nous fournissent l'évènement onLoadProgress qui correspond exactement à ce besoin:

mclListener.onLoadProgress = function(mc:MovieClip, loadedBytes:Number, totalBytes:Number) {
	var width:Number = (loadedBytes / totalBytes) * 200;
	drawFilledRectangle(progressMC, 100, 140, width, 15, 0xffffff, 100);
}

Et nous obtenons:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.
Code complet en pièce jointe: 5)

C'est la première fois que nous utilisons une méthode d'écouteur d'évènement qui reçoit des paramètres, arrêtons-nous y un peu:

Au cours du chargement, l'évènement onLoadProgress est diffusé régulièrement. La méthode correspondante de l'écouteur mclListener est appelée à chaque fois, et trois paramètres lui sont passés, dans l'ordre: une référence au MovieClip qui est chargé, le nombre d'octets chargés, et le nombre total d'octets à charger.

Nous n'avons donc qu'à déclarer ces trois paramètres dans l'en-tête de notre fonction, pour les recevoir et les utiliser. Le paramètre mc ne nous sert à rien, mais nous devons quand même le déclarer.

Dans le corps de la fonction, vous l'avez compris je pense, nous calculons la largeur du remplissage width, puis nous appelons drawFilledRectangle pour remplir la barre de progression à cette largeur.


V - Des barres de progression, oui, mais le moins possible

Nous avons bien avancé. Mais personnellement, quelque chose me chagrine: L'affichage systématique de la barre de progression nuit sérieusement au rendu de notre joli fondu enchaîné entre les images.

Dans le cas où le téléchargement est court, par exemple pour des images légères, ou bien pour les images déjà visualisées une fois, donc présentes dans le cache du navigateur, ne serait-il pas préférable de nous passer de l'apparition de la barre de progression?

Voyons ce que l'on peut faire.

1- Ne pas afficher la barre dès le début du chargement

Pour commencer, supprimons l'affichage systématique de la barre de progression en effaçant la méthode onLoadStart de mclListener, en en faisant une nouvelle fonction afficherProgressMC:

function afficherProgressMC() {
	progressMC.clear();
	drawFilledRectangle(progressMC, 0, 0, 400, 300, 0, 50);
	drawRectangle(progressMC, 100, 140, 200, 15, 2, 0xffffff, 100);
	progressMC._visible = true;
}

2- Mémoriser le moment où le chargement est demandé

Nous allons stocker dans une variable le moment où l'utilisateur clique sur un bouton. Nous nous servirons de cette valeur pour n'afficher la barre de progression que si le chargement dure plus de 1 seconde. Introduisons une nouvelle variable et modifions la fonction chargerImage:

var startLoadTime:Number;
function chargerImage() {
	startLoadTime = getTimer();
	mcl.loadClip("images/image" + imageActuelle + ".jpg", imageChargementMC);
}

getTimer est une fonction globale (en savoir plus) qui renvoie le nombre de millisecondes écoulées depuis le début de l'exécution du swf.

3- Attendre 1 seconde pour afficher la barre de progression

Dans la fonction onLoadProgress, nous allons surveiller le temps passé depuis le début du chargement, et afficher progressMC uniquement si 1 seconde s'est écoulée:

mclListener.onLoadProgress = function(mc:MovieClip, loadedBytes:Number, totalBytes:Number) {
	if (!progressMC._visible) {
		var loadTime:Number = getTimer() - startLoadTime;
		if (loadTime > 1000) afficherProgressMC();
	}
	if (!progressMC._visible) return;
	var width:Number = (loadedBytes / totalBytes) * 200;
	drawFilledRectangle(progressMC, 100, 140, width, 15, 0xffffff, 100);
}

4- Le résultat

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.
Code complet en pièce jointe: 6)

Faites tourner le diaporama. Dans le cas de l'affichage d'une image déjà vue, donc dans le cache, le téléchargement dure moins de 1 seconde, la barre de progression n'est plus affichée, et nous retrouvons la transition en douceur de notre fondu enchaîné.

5- Explications

Quand l'utilisateur clique sur un bouton, la fonction chargerImage mémorise dans la variable startLoadTime le moment du clic.

Le chargement démarre. Notre nouvelle fonction onLoadProgress commence par tester si progressMC est déjà affiché:

if (!progressMC._visible) {

Le point d'exclamation est l'opérateur booléen de négation. C'est-à-dire que si progressMC._visible est vrai, alors !progressMC._visible est faux. Le bloc d'instruction entre les accolades ne sera donc exécuté que si progressMC n'est pas affiché.

var loadTime:Number = getTimer() - startLoadTime;

Ceci calcule le nombre de millisecondes écoulées entre le moment présent (getTimer) et le moment où le chargement à commencé (startLoadTime). Le résultat de ce calcul est stocké dans une nouvelle variable loadTime.

if (loadTime > 1000) afficherProgressMC();

Si plus de 1 seconde (1000 millisecondes) s'est écoulée depuis le début du chargement, on initialise et affiche progressMC.

Exécuté ou pas, le bloc d'instruction conditionnel entre accolades est terminé, et flash passe à la ligne suivante:

if (!progressMC._visible) return;

Si progressMC n'est toujours pas affiché, l'instruction return est exécutée. Cette instruction signifie à flash que la fonction est terminée. Le code qui suit, qui dessine le rectangle de remplissage, ne sera donc pas exécuté.

Dans le cas contraire, c'est que progressMC est visible, et le code que nous connaissons déjà s'occupe de remplir la barre de progression:

var width:Number = (loadedBytes / totalBytes) * 200;
drawFilledRectangle(progressMC, 100, 140, width, 15, 0xffffff, 100);


Conclusion

Et voilà un gros morceau terminé! J'espère que vous avez suivi avec un minimum de problèmes (quoique rencontrer des problèmes est peut-être le plus formateur!). Pour faire progresser ce tutoriel, j'attends toujours vos commentaires sur le forum. Vous pouvez répondre au message concernant ce tutoriel ou ouvrir un nouveau sujet.

En naviguant sur internet, vous avez sûrement rencontré bien des barres de progression différentes. Ce peut être le moment pour vous de prendre une pause dans la lecture de cette série de tutoriaux, et d'essayer d'en réaliser une personnalisée. Certaines affichent également en pourcentages la quantité déjà téléchargée, et je vous laisse sur cette suggestion d'exercice, la solution se trouvant en pièce jointe 7)

Dans le prochain article, nous verrons comment pré-charger les images sans attendre que l'utilisateur demande à les voir, ce qui accélérera leur affichage et nous permettra de n'afficher la barre de progression que le moins souvent possible.


Pour en savoir plus

Pour avoir des précisions ou des renseignements complémentaires à ce tutoriel, vous pouvez consulter 8) :

  • Au sujet des fonctions globales, comme getTimer: Aide de Flash > Référence du langage ActionScript 2.0 > Eléments du langage ActionScript > Fonctions globales.
  • Au sujet des chargements et de MovieClipLoader:
    • La section Charger du contenu : images, animations, classes du wiki. Plusieurs bons tutoriaux. Notamment celui-ci : Préchargement/Preload
    • Aide de Flash > Référence du langage ActionScript 2.0 > Classes ActionScript > MovieClipLoader
    • Aide de Flash > Formation à ActionScript 2.0 dans Adobe Flash > Utilisation des images, du son et de la vidéo > Chargement de fichiers SWF et de fichiers d'images externes
  • Au sujet des instructions conditionnelles et des conditions (if):
    • Aide de Flash > Formation à ActionScript 2.0 dans Adobe Flash > Eléments fondamentaux du langage et de la syntaxe > Présentation des instructions > Présentation des conditions.


Navigation: Sommaire page précédente page suivante Index

1) , 2) , 3) , 4) , 5) , 6) , 7) Vous pouvez télécharger les fichiers de code correspondants à cet article et les swf compilés dans une archive compressée. Si vous utilisez Flash IDE, cliquez ici. Si vous utilisez un environnement intégrant mtasc et swfmill, cliquez ici
8) Les références à l'aide de Flash concernent la documentation de Flash CS3, accessible par l'IDE de Flash CS3 ou par le site d'Adobe (Support > Documentation).