Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Diaporama pas à pas - 5 - Les barres de progression du téléchargement - 1 - TextField et les méthodes de dessin

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

Objectif

Cinquième volet de la série de tutoriaux commencée ici, qui propose la création d'un diaporama en ligne, avec explications détaillées à l'usage des débutants en ActionScript 2 (qui commencent d'ailleurs à l'être un peu moins, s'ils sont arrivés jusqu'ici :-D ).

Nous revoici à pied d'oeuvre pour ajouter à notre diaporama les célèbres et incontournables barres de progression du téléchargement.

Ainsi:

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


Accordons nos violons

Comme notre diaporama charge les images au fur et à mesure, il s'ensuit des temps de chargements qui ralentissent l'arrivée des images à l'affichage. Selon le poids des images (leur taille en octets) et la rapidité de la connexion de l'utilisateur au réseau internet, ces temps peuvent être plus ou moins longs. De plus en plus de monde a une connexion haut débit, et le temps de chargement d'une image compressée et optimisée pour un affichage à l'écran devient presque négligeable. Ceci ne va pas nous empêcher de nous pencher sur le problème, pour les raisons suivantes:

  • Il y a toujours des connexions bas débit ici ou là.
  • On n'est jamais à l'abri d'un ralentissement du débit.
  • On peut vouloir faire un diaporama plein écran de grandes images, d'une très bonne qualité, donc lourdes à charger.
  • La méthode loadClip que nous utilisons pourrait également charger des animation swf à la place d'image jpg. Nous pourrions sans rien changer au code faire un “diaporama d'animations”, et ces animations pourraient être lourdes à charger.
  • C'est un bon sujet pédagogique pour continuer l'apprentissage d'ActionScript, et la méthode utilisée pourra resservir dans un tout autre cadre que celui d'un diaporama.

Ceci dit, pourquoi charger les images au fur et à mesure, et pas une bonne fois pour toute au début? Tout simplement car ce serait long et ferait attendre l'utilisateur. Nous préférons lui proposer le plus rapidement possible l'apparition de la première image sur son écran. Par la suite, nous verrons comment précharger de façon transparente pour l'utilisateur toutes les images après que la première se soit affichée. Mais… une chose à la fois ;-) !


Connaissances requises pour cet article

Rien de plus que pour les précédents.


La méthode

Quand l'utilisateur change d'image, nous voulons faire apparaître le message “Chargement en cours…”, et dessiner sous ce message un rectangle dont la taille augmente au fur et à mesure du téléchargement (voyez l'exemple ci-dessus).

Nous avons donc besoin de savoir faire deux choses encore inconnues: Afficher du texte et dessiner un rectangle.

Nous allons apprendre ces deux choses l'une après l'autre, et séparément de la réalisation du diaporama lui-même. Cela va occuper la totalité de cette page. Puis nous intégrerons le tout dans notre diaporama, en page suivante.

Comme d'habitude, le code utilisé tout au long de cette page se retrouve intégralement en pièce jointe: 1)


I - Afficher du texte sur la scène

Pour afficher du texte, nous avons besoin de la classe TextField. Un objet de cette classe, ou plutôt occurence de cette classe, pour utiliser le terme consacré, permet d'afficher sur un MovieClip un champ de texte d'une dimension donnée, contenant un texte donné, avec une mise en forme (choix de la police, taille, couleur, etc) donnée.

1- Le service minimum

Pour créer le TextField nous devons utiliser la méthode de MovieClip nommée createTextField. Créez un nouveau document, donnez à la scène les dimensions 400×50 pixels et une autre couleur que le noir, et entrez le code suivant:

var tf:TextField = this.createTextField("champTexte", 0, 150, 20, 100, 30);
tf.text = "Un peu de texte";

Exécutez, vous devriez avoir le résultat suivant:

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

Ce n'est pas compliqué. this désigne la scène, c'est un MovieClip, donc elle a une méthode createTextField. On appelle cette méthode pour créer en profondeur 0 un champ de texte nommé champTexte. Les quatre autres paramètres numériques passés à la méthode createTextField correspondent aux coordonnées du champ de texte à créer (150, 20) et aux dimensions (100×30 pixels) que l'on désire lui donner.

Sur la même ligne on crée une variable de type TextField qui nous servira par la suite à désigner le champ de texte.

Sur la seconde ligne on modifie la propriété text du TextField. Cette propriété est une chaîne de caractères (notion déjà introduite en deuxième partie), d'où l'utilisation des guillemets. On affecte à cette propriété la valeur “Un peu de texte” et flash affiche alors le texte correspondant.

On peut voir le champ de texte comme un rectangle invisible, dont le coin supérieur gauche est placé aux coordonnées (150,20), de largeur 100 pixels, et de hauteur 30 pixels. C'est dans la zone définie par ce rectangle que l'on peut faire apparaître du texte. Si on affecte à la propriété text une trop longue chaîne de caractères, celle-ci sera “tronquée”, comme cela:

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.
tf.text = “Un texte trop long pour tenir dans son champ”;

2- Raffinons

Un TextField a bien d'autres propriétés, qui permettent de contrôler l'affichage du texte. Par exemple il y a une propriété nommée autoSize qui permet d'indiquer que l'on désire que la taille du champ s'adapte automatiquement aux dimensions du texte à représenter. Donc si l'on rajoute à notre code:

tf.autoSize = "left";

Le problème précédent est résolu:

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

Autre propriété que nous allons utiliser: textColor, qui permet de choisir la couleur du texte:

tf.textColor = 0xaa0022;

Ce qui donne:

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

Si vous n'êtes-vous pas familier de l'utilisation des couleurs RVB en hexadécimal, la notation 0xaa0022 doit vous sembler bien étrange.
0xaa0022 est un nombre, tout simplement. En utilisant notre façon habituelle de compter, en décimal, ce nombre vaut 11141154. Ici, il est représenté en hexadécimal. C'est ce que signifie l'entête 0x, qui dit à flash: lit la succession de chiffres et de lettre aa0022 comme un nombre hexadécimal.

Les couleurs affichables sur un écran sont codées par une valeur hexadécimale. Le sujet est largement traité ailleurs, aussi je vous donne quelques liens pour vous documenter. Vous pouvez en trouver bien d'autres en tapant “couleur rvb hexadécimal” dans un moteur de recherche:

Je me contenterais de ces propriétés pour l'instant. Bien sûr flash permet d'aller plus loin dans le contrôle de l'affichage du texte, et de choisir tous les paramètres comme on peut le faire dans un traitement de texte. Par exemple:

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

Le code correspondant est en pièce jointe 2). Je vous invite à découvrir cela par vous-même, en lisant notamment l'aide de flash pour la classe TextField. Voyez Pour en savoir plus au bas de la page. Vous pouvez également vous rendre à la neuvième partie, où nous en verrons plus.


II - Dessiner le contour d'un rectangle

Après une petite pause bien méritée, en ce qui me concerne, lançons-nous maintenant dans le dessin des rectangles.

La classe MovieClip a des méthodes permettant de tracer des dessins lors de l'exécution du swf. La scène étant un MovieClip, elle possède ces méthodes. Créez donc un nouveau document, disons de 300×200 pixels, pour faire nos essais.

1- Le code

this.lineStyle(4, 0x0000ff, 100);
this.moveTo(20, 20);
this.lineTo(280,20);
this.lineTo(280,180);
this.lineTo(20,180);
this.lineTo(20,20);

2- Le beau résultat

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

3- Explications

C'est un peu comme si chaque MovieClip avait son dessinateur personnel:

lineStyle(4, 0x0000ff, 100) demande au dessinateur du MovieClip de prendre en main un crayon de 4 pixels d'épaisseur, de couleur 0x0000ff (bleu), et d'opacité 100%.

moveTo(20, 20) demande au dessinateur de poser son crayon au point de coordonnées (20, 20). Rien n'est encore dessiné.

lineTo(280,20) demande au dessinateur de déplacer son crayon jusqu'au point (280, 20). Le crayon laisse alors sa trace sur le MovieClip et un trait horizontal, de 260 pixels de large, apparaît.

lineTo(280,180), lineTo(20,180) et lineTo(20,20) font passer le crayon par tous les coins du rectangle. Sont alors dessinés successivement les bords droit, bas et gauche du rectangle.

Si vous êtes toujours un peu confus avec le système des coordonnées des points sur la scène, je vous invite à relire le début de cet article, et à faire vos essais.


III - Notre première fonction avec passage de paramètres

Dessiner le contour d'un rectangle est une opération courante, mais rien n'est prévu en ActionScript 2 pour le faire automatiquement. Ce serait quand même bien commode d'avoir une fonction qu'il suffirait d'appeler pour dessiner un rectangle en une ligne de code.

Très bien! Nous allons en profiter pour écrire notre propre fonction drawRectangle (dessiner un rectangle, en anglais).

Comme cela, si nous avons plus d'un rectangle à dessiner, il nous suffira d'appeler la fonction, au lieu d'avoir à retaper les 6 lignes de code nécessaires. Et cela va nous donner l'occasion d'écrire notre première fonction avec des paramètres.

1- Le code

Remplacez tout le code précédent par:

// Définition de la fonction:
function drawRectangle(
	mc:MovieClip,
	x:Number, y:Number, width:Number, height:Number,
	thickness:Number, rgb:Number, alpha:Number
) {
	mc.lineStyle(thickness, rgb, alpha);
	mc.moveTo(x, y);
	mc.lineTo(x + width, y);
	mc.lineTo(x + width, y + height);
	mc.lineTo(x, y + height);
	mc.lineTo(x, y);
}
// Appel de la fonction
drawRectangle(this, 20, 20, 260, 160, 4, 0x0000ff, 100);

Exécutez, le résultat doit être exactement le même.

L'avantage, c'est que si nous voulons dessiner d'autres rectangles, il suffit d'ajouter:

drawRectangle(this, 30, 30, 160, 100, 2, 0xff0000, 100);
drawRectangle(this, 140, 100, 110, 90, 5, 0xff9900, 80);
drawRectangle(this, 260, 40, 30, 30, 7, 0xffff00, 85);

Et voilà 3 autres rectangles supplémentaires:

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

2- Explications

Nous abordons là une fonctionnalité courante en programmation: Le passage de paramètres, aussi appelés arguments, à une fonction. C'est un outil puissant, qui va nécessiter quelques explications. Prenez votre temps, le jeu en vaut la chandelle.

Les paramètres sont les éléments que l'on “passe” à une fonction en l'appelant, et qui vont préciser ce qu'on lui demande de faire. Nous avons déjà souvent passé des paramètres à des fonctions (ou a des méthodes, qui ne sont rien d'autre que des fonctions attachées à un objet). Par exemple this.createEmptyMovieClip(“unClip”, 8) appelle la méthode createEmptyMovieClip en lui passant deux paramètres: la chaîne de caractères “unClip” et le nombre 8.

Nous avons déjà écrit nos propres fonctions, par exemple:

function chargerImageSuivante() {
	imageActuelle++ ;
	if (imageActuelle == 4) imageActuelle = 0;
	chargerImage();
}

Cette fonction fait toujours la même chose: elle augmente imageActuelle de 1, revient à 0 si nécessaire, et appelle chargerImage. Nous n'avions donc pas besoin de paramètres.

Avec notre fonction drawRectangle nous sommes dans un cas où nous avons besoin de paramètres, car il ne s'agit pas de dessiner à chaque fois un rectangle identique. Nous voulons pouvoir passer à la fonction les coordonnées du rectangle et son type de trait. On introduit les paramètres dans l'en-tête de la déclaration de la fonction, de la façon suivante:

function drawRectangle(
	mc:MovieClip,
	x:Number, y:Number, width:Number, height:Number,
	thickness:Number, rgb:Number, alpha:Number
) {
	//Ici on met le "corps" de la fonction
}

Ceci veut dire: Voilà une fonction qui s'appelle drawRectangle, et qui attend qu'on lui passe comme paramètres, dans l'ordre, un MovieClip puis 7 nombres. On déclare les paramètres entre les parenthèses qui suivent le nom de la fonction, séparés par des virgules. On écrit ensuite le code correspondant à la fonction entre des accolades.

Par la suite, quand on appellera la fonction par

drawRectangle(this, 20, 20, 260, 160, 4, 0x0000ff, 100);

les variables mc, x, y, width, height, thickness, rgb, alpha, seront créées et affectées des valeurs correspondantes. Dans le corps de la fonction, on pourra utiliser ces variables. Ainsi,

mc.lineStyle(thickness, rgb, alpha);

définira le style de trait pour le MovieClip mc (donc la scène) avec une épaisseur thickness (donc 4), une couleur rgb (donc 0x0000ff) et une opacité alpha (donc 100).

mc.moveTo(x, y);

Placera le crayon au point de coordonnées (x, y), c'est-à-dire (20, 20).

mc.lineTo(x + width, y);

Tracera une ligne jusqu'au point coordonnées (x + width, y), c'est-à-dire (20+260,20), c'est-à-dire (280,20).

Et ainsi de suite.

3- Remarques

Voici maintenant quelques points importants à connaître, que je ne peux passer sous silence. Si vous arrivez à ce point épuisés par tant de connaissances nouvelles :-) et que vous préférez avancer dans la réalisation du diaporama, vous pouvez vous contenter de lire la première remarque. Vous pourrez revenir ultérieurement sur les autres points.

Remarque 1: Sur la rédaction de l'en-tête

Comme drawRectangle attend plusieurs paramètres, je suis revenu à la ligne dans la déclaration, pour rendre le code plus lisible. Mais

function drawRectangle(mc:MovieClip, x:Number, y:Number, width:Number, height:Number, thickness:Number, rgb:Number, alpha:Number) {
	//Ici on met le "corps" de la fonction
}

serait tout aussi valable.

Remarque 2: Variables locales / variables de scénario

Lors de l'exécution de la fonction, on dispose donc des variables déclarées comme paramètres. On parle de variables locales à la fonction. C'est-à-dire que ces variables sont créées au moment de l'appel de la fonction, existent le temps que la fonction s'exécute, puis sont détruites quand la fonction prend fin. Ceci veut dire que l'utilisation de ces variables n'est valide que dans le corps de la fonction. Si on essaie d'utiliser ces variables à un autre endroit du code, à l'extérieur de la fonction, on aura une erreur. Par exemple le code

function drawRectangle(
	mc:MovieClip,
	x:Number, y:Number, width:Number, height:Number,
	thickness:Number, rgb:Number, alpha:Number
) {
	mc.lineStyle(thickness, rgb, alpha);
	mc.moveTo(x, y);
	mc.lineTo(x + width, y);
	mc.lineTo(x + width, y + height);
	mc.lineTo(x, y + height);
	mc.lineTo(x, y);
}
drawRectangle(this, 20, 20, 260, 160, 4, 0x0000ff, 100);
trace(thickness);

dessinera bien un rectangle sur la scène, mais n'affichera pas “4” dans la fenêtre de sortie. Nous verrons à la place s'afficher “undefined”, qui nous confirme que la variable thickness n'existe pas en dehors de la fonction.

Inversement, les variables qui sont déclarées à l'extérieur des déclarations de fonctions sont des variables dites de scénario, c'est-à-dire définies et utilisables à n'importe quel endroit du code exécuté après leur déclaration, y compris dans les fonctions. C'est le cas par exemple pour la variable imageActuelle, qui est utilisée par les fonctions chargerImageSuivante et chargerImagePrecedente.

Remarque 3: Typer les paramètres

Il n'est pas obligatoire de donner le type de chaque paramètre. On peut très bien coder:

function drawRectangle(mc, x, y, width, height, thickness, rgb, alpha) {
	//Ici on met le "corps" de la fonction
}

Mais je vous le déconseille fortement. “Typer” les variables permet d'éviter des erreurs. Par exemple, avec cette dernière déclaration on pourrait appeler

drawRectangle(this, "20", this, 260, 160, "très épais", 0x0000ff, 100);

sans que flash nous signale une erreur à cet endroit. Tandis que si on fait la même chose en ayant “typé” les variables, flash nous signalera un appel incorrect à la fonction drawRectangle pour cause de type de paramètre incorrect: En effet, on passe la chaîne de caractères “20” alors que la fonction attend un nombre comme deuxième paramètre, et on passe un MovieClip comme troisième paramètre alors que la fonction attend un nombre.

4- Un peu de pratique

Si vous n'avez jamais encore écrit de fonctions attendant des paramètres, je crois que quelques exercices seraient bienvenus pour vous familiariser avec cet outil.

a) Essayez donc d'écrire une fonction qui dessine un carré, et qui attend comme paramètres une référence au MovieClip où l'on doit dessiner, les coordonnées du coin supérieur gauche du carré, la longueur du côté du carré, et le style de trait.

b) Essayez d'écrire une fonction qui dessine également un carré, et qui attend cette fois comme paramètres une référence au MovieClip où l'on doit dessiner, les coordonnées du centre du carré, la longueur du côté du carré, et le style de trait.

c) Essayez d'écrire une fonction qui modifie le texte d'un TextField qui est sur la scène. Cette fonction attend comme paramètre une référence au TextField que l'on doit modifier, la chaîne de caractères à afficher, et la couleur à utiliser. Utilisez cette fonction pour modifier le texte de 3 TextFields que vous aurez préalablement créés sur la scène. L'en-tête de la fonction sera donc:

function ecrire(tf:TextField, texte:String, color:Number) {}

(Le type String veut dire “chaîne de caractères”)

Le résultat ressemblera à ceci:

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

Les solutions se trouvent comme d'habitude en pièce jointe: 3)


IV - Dessiner un rectangle plein

Voyons pour finir comment dessiner un rectangle plein, ce qui nous servira à remplir progressivement nos barres de progression.

1- Le code

Créez un nouveau document avec le code suivant:

function drawFilledRectangle(
	mc:MovieClip,
	x:Number, y:Number, width:Number, height:Number,
	rgb:Number, alpha:Number
) {
	mc.beginFill(rgb, alpha);
	mc.moveTo(x, y);
	mc.lineTo(x + width, y);
	mc.lineTo(x + width, y + height);
	mc.lineTo(x, y + height);
	mc.endFill();
}
drawFilledRectangle(this, 20, 20, 260, 160, 0x0000ff, 100);
drawFilledRectangle(this, 30, 30, 160, 100, 0xff0000, 100);
drawFilledRectangle(this, 140, 100, 110, 90, 0xff9900, 80);
drawFilledRectangle(this, 260, 40, 30, 30, 0xffff00, 85);

2- Le splendide résultat

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

3- Explications

Il y a peu de changements par rapport au dessin du contour seul. Au lieu de donner les caractéristiques du crayon avec lineStyle, on donne la couleur et l'opacité du remplissage avec beginFill. beginFill dit au dessinateur: A partir de maintenant, les lignes que l'on va tracer sont les côtés d'un polygone dont tu rempliras au fur et à mesure l'intérieur. Puis on parcours les côtés du rectangle avec les lineTo, et on finit en appelant endFill qui signifie au dessinateur que le remplissage est terminé.

Remarquons qu'il n'est pas utile de revenir au point de départ par un dernier mc.lineTo(x, y) .

4- Pour la route

Je ne résiste pas à vous suggérer la réalisation suivante: Ecrire une fonction qui utilise les deux fonctions drawRectangle et drawFilledRectangle pour dessiner des rectangles pleins avec un contour d'une autre couleur, solution en pièce jointe 4).

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


Conclusion

Nous voilà équipés des outils qui vont nous permettre de dessiner les barres de progression. Et bien au-delà, vous avez appris à écrire des fonctions qui reçoivent des paramètres, notion indispensable de programmation.

Nous n'avons plus qu'à réinvestir ces fonctions et connaissances dans notre diaporama, ce qui fait l'objet de la page suivante.

En attendant, n'hésitez surtout pas à poser vos questions ou à faire vos remarques sur ce tutoriel, sur le forum. Seuls vos retours permettront de l'améliorer. Vous pouvez répondre au message concernant ce tutoriel ou ouvrir un nouveau sujet. Merci beaucoup.


Pour en savoir plus

Pour avoir des précisions ou des renseignements complémentaires, vous pouvez consulter 5) :

  • Au sujet de la classe TextField et du formatage de texte:
    • Aide de Flash > Référence du langage ActionScript 2.0 > Classes ActionScript > TextField
    • Aide de Flash > Référence du langage ActionScript 2.0 > Classes ActionScript > TextFormat
    • Aide de Flash > Formation à ActionScript 2.0 dans Adobe Flash > Utilisation du texte et des chaînes
    • La neuvième partie de ce tutoriel
  • Au sujet des méthodes de dessin:
    • Aide de Flash > Formation à ActionScript 2.0 dans Adobe Flash > Animation, Filtres et Dessins > Dessin à l'aide du code ActionScript
    • Dessinons sur des clips sur le siteduzero.
  • Au sujet des fonctions et des paramètres:
    • Aide de Flash > Formation à ActionScript 2.0 dans Adobe Flash > Fonctions et méthodes > Présentation des fonctions et des méthodes.
    • Et plus spécialement Aide de Flash > Formation à ActionScript 2.0 dans Adobe Flash > Fonctions et méthodes > Présentation des fonctions et des méthodes > Transmission de paramètres à une fonction.
  • Au sujets des variables locales et de scénario:
    • Aide de flash > Formation à ActionScript 2.0 dans Adobe Flash > Données et types de données > Présentation des variables > Variables et domaine.
    • Un article très instructif du wiki sur la “chaîne de portée”.


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

1) , 2) , 3) , 4) 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
5) 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).