TUTORIEL FLASH 
Des formes complexes avec l'API de dessin Flash
Second volet de notre approche de la Drawing API, avec la création de cercles et de polygones réguliers, et une manière de rendre la création de formes interactive. (04/01/2005)

Comme nous l'avons vu à la fin de notre premier article sur le sujet, la Drawing API de Flash permet non-seulement de tracer des lignes et des courbes, et de les remplir, mais également, par le biais d'ActionScript, de facilement créer des fonctions permettant l'automatisation de la création de formes complexes. Nous allons en voir quelques-unes avec cet article.

Nous avons déjà vu comment construire et placer "automatiquement" (pour peut que l'on fournisse les valeurs adéquats) un rectangle (et donc, par extension, un carré). Les autres formes que nous allons aborder sont

Le cercle
Nous avons vu la méthode curveTo(), qui permet donc de créer une courbe à partir de trois. En toute bonne logique, comme pour le rectangle, quatre appels à cette fonction et nous obtiendrons un cercle. C'est en fait plus compliqué que cela.
Si nous faisons seulement appel quatre fois à curveTo(), comme ceci :

with ( _root.cercle )
  {
  lineStyle( 2, 0x00000, 100 );
  moveTo( 100, 100 );
  curveTo( 120, 100, 120, 80 );
  curveTo( 120, 60, 100, 60 );
  curveTo( 80, 60, 80, 80 );
  curveTo( 80, 100, 100, 100 );
  }

(cercle étant un MovieClip sur la scène, créé par exemple avec _root.createEmptyMovieClip( "cercle", 1 );)

…nous obtenons certes une forme arrondie, mais sans être un cercle : il n'y a pas assez de courbe, ce qui entraîne une distorsion du rond prévu. Nous avons affaire à des courbes de Bezier quadratiques (trois points d'ancrage).
Il nous faut doubler le nombre de curveTo() pour obtenir un cercle correct : notre fonction en utilise donc huit, afin de se rapprocher d'un résultat obtenu avec quatre courbes de Bézier cubiques (quatre points d'ancrage). Chacune de ces huit courbes s'occupe de 45° du diamètre du cercle (1/8e de 360°…).
Nos points de départs et d'arrivée sont donc des "points de passage" de la courbe, et le point de contrôle, qui défini la courbe elle-même de cette section, se trouve placé au croisement de la tangente du cercle au point de départ (ou d'arrivée) et de la bissectrice de cet angle. La distance du centre du cercle au point de contrôle en cours correspond ainsi à l'hypoténuse du triangle rectangle.

De nombreuses fonctions existent pour parvenir à calculer et afficher le résultat. Voici l'une des plus compréhensibles :

MovieClip.prototype.drawCircle = function(rayon, x, y) {
  var deltaAngle = Math.PI / 4;
  var ctrlDist = rayon / Math.cos(deltaAngle / 2);
  var angle = 0;
  var departx, departy, arriveex, arriveey;
  this.moveTo(x + rayon, y);
  for (var i = 0; i < 8; i++) {
    angle += deltaAngle;
    departx = x + Math.cos(angle - (deltaAngle / 2)) * ctrlDist;
    departy = y + Math.sin(angle - (deltaAngle / 2)) * ctrlDist;
    arriveex = x + Math.cos(angle) * rayon;
    arriveey = y + Math.sin(angle) * rayon;
    this.curveTo(departx, departy, arriveex, arriveey);
    }
  };
var cercle = this.createEmptyMovieClip("cercle", 1);
cercle.lineStyle(0, 0x000000, 100);
cercle.drawCircle(80, 100, 100);

Le polygone régulier
Autre forme intéressante à réaliser, un polygone dont tous les cotés sont égaux, construit à partir du nombre de côtés désirés, et de la longueur de chaque côté. Ici encore les mathématiques devront être utilisées, car il nous faut déterminer l'angle nécessaire pour construire notre polygone (c'est-à-dire l'angle entre deux segments de deux sommets consécutif. Cet angle est égale à 2PI divisé par le nombre de cotés.
Chacun des sommets est ensuite placé sur un cercle de rayon égale à un segment. Enfin, nous calculons les position X et Y de chaque sommet au moyen des fonctions trigonométriques, au sein d'une boucle for().
Voici la méthode utilisée :

MovieClip.prototype.polyReg = function(cotes, longueur, rotation, x, y) {
  rotation = (Math.PI*rotation/180);
  var angle = (2*Math.PI)/cotes;
  var rayon = (longueur/2)/Math.sin(angle/2);
  var px = (Math.cos(rotation)*rayon)+x;
  var py = (Math.sin(rotation)*rayon)+y;
  this.moveTo(px, py);
  for (var i = 1; i<=cotes; i++) {
    px = (Math.cos((angle*i)+rotation)*rayon)+x;
    py = (Math.sin((angle*i)+rotation)*rayon)+y;
this.lineTo(px, py);
    }
  };

  Forum

Réagissez dans les forums de JDN Développeurs

Il est bien entendu possible de laisser à l'utilisateur la possibilité de choisir lui-même une forme. Construisons par exemple une interface permettant de choisir chacune des 5 valeurs de polyRef().
Glissez sur la scène 6 composants NumericStepper (disponible dans Flash MX 2004), dont et nommez-les stepCotes, stepLongueur, stepAngle, stepX, stepY et stepStylo. Ce compostant dispose d'une méthode, change, que nous allons exploiter pour récupérer un de ses attributs, value.
Chaque composant doit avoir des valeurs de maximum, minimum, stepSize et value clairement défini pour éviter les surprises. stepCotes doit ainsi avoir un minimum de 3, et stepAngles doit avoir un maximum allant à 360 et un minimum allant à -360…
Reste ensuite à faire la liaison entre le code et notre fonction polyReg(). Nous ferons cela au travers d'un objet générique qui lance une majPoly() comme suit :

function majPoly() {
  polygone.clear();
  polygone.lineStyle(stepStylo.value, 0x000000, 100);
  polygone.polyReg(stepCotes.value, stepLongueur.value,   stepAngle.value, stepX.value, stepY.value);
  }

clear() efface le contenu de notre MovieClip, ce qui permet de ne pas dessiner les polygones les uns par-dessus les autres.
Voici la définition de notre objet, et les gestionnaires d'événement que nous lui attachons :

ecouteurPoly.change = function()
  {
  majPoly();
  };
stepCotes.addEventListener("change", ecouteurPoly);
stepLongueur.addEventListener("change", ecouteurPoly);
stepAngle.addEventListener("change", ecouteurPoly);
stepX.addEventListener("change", ecouteurPoly); stepY.addEventListener("change", ecouteurPoly);
stepStylo.addEventListener("change", ecouteurPoly);

Cela ouvre la voie a des applications de dessins, par exemple...

 
Xavier Borderie, JDN Développeurs
 
Accueil | Haut de page
 
 





Quand achetez-vous le plus en ligne ?
Du lundi au vendredi
Le samedi
Le dimanche

Tous les sondages