![]()
Méthodes et classes de l’API de dessin du lecteur flash v10 (Flash CS4) utilisés dans cet article :
flash.display.GraphicsSolidFill
flash.display.GraphicsPath
flash.display.GraphicsStroke
flash.display.IGraphicsData
flash.display.Graphics.drawGraphicsData()
flash.display.Graphics.drawPath()
![]()
Pour cette présentation, j’ai mis en place un script qui permet de stocker les commandes de dessin (simple) de l’utilisateur, elles peuvent être ensuite répliqués et modifiés a volonté.
- Dans la partie gauche de l’animation, un
TextFieldaffiche la manière dont les données de dessin sont stockés dans la variableGraphicsPath.
c=1 correspond a une méthodemoveTo()
c=2 correspond a une méthodelineTo()
les coordonnées sont la position X et Y. - La partie centrale permet de dessiner une forme a la souris.
- le cadre en bas a droite est une miniature de la scène.
Les touches du clavier à utiliser :
- ENTRER = Effacer toutes les données et le dessin.
- ESPACE = recréer le dessin a partir des données stockés et créer la miniature du dessin de la scene.
- SUPPRIMER = Effacer le dessin de la scène sans effacer les données.
le code :
package { import flash.display.GraphicsPath; import flash.display.Graphics; import flash.display.IGraphicsData; import flash.display.GraphicsStroke; import flash.display.GraphicsSolidFill; import flash.display.Sprite; import flash.display.Shape; import flash.events.Event; import flash.events.KeyboardEvent; import flash.events.MouseEvent; import flash.text.TextField; import flash.text.TextFormat; import flash.ui.Keyboard; import flash.utils.getTimer /** * @author Lorenzo * * Test des nouvelles possibilités de l'API de dessin de Flash 10 : drawGraphicsData + GraphicsPath + drawPath + GraphicsStroke + .... * * -on dessine ce que l'on veut * -on appuye DELETE pour effacer le dessin * -on appuye sur SPACE pour recreer le dessin * -on appuye sur ENTER pour tout remettre a zero * * une miniature du dessin est affiché en bas a droite */ public class Main5 extends Sprite { // ----------------------------------------------------------------------------------- // DECLARATIONS // ----------------------------------------------------------------------------------- private static const THICKNESS:uint = 1; private static const COLOR:uint = 0xFF0000; // le nombre max de données a stocker private static const MAX_LIGNES:uint = 20000; private var _txCode:TextField; private var _shapeMiniature:Shape; private var _shapeMiniatureContour:Shape; // les données de dessin (commandes (moveTo/lineTo) et coordonnées) private var _path:GraphicsPath = new GraphicsPath(new Vector.<int>(), new Vector.<Number>()); // ----------------------------------------------------------------------------------- // CONSTRUCTEUR // ----------------------------------------------------------------------------------- public function Main5():void { if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } private function init(e:Event = null):void { removeEventListener(Event.ADDED_TO_STAGE, init); stage.scaleMode = "showAll"; this._txCode = new TextField(); this._txCode.width = 100; this._txCode.height = 800; this._txCode.background = true; this._txCode.defaultTextFormat = new TextFormat("Arial", 11); this._txCode.mouseWheelEnabled = true; this.addChild(this._txCode); this.graphics.lineStyle(THICKNESS, COLOR); // conteneur miniature this._shapeMiniatureContour = new Shape(); this._shapeMiniatureContour.graphics.lineStyle(1, 0xFFFFFF, 0.5); this._shapeMiniatureContour.graphics.beginFill(0xAAAAAA, 0.5); this._shapeMiniatureContour.graphics.drawRect(0, 0, 200, 200); this._shapeMiniatureContour.x = 600; this._shapeMiniatureContour.y = 400; this.addChild(this._shapeMiniatureContour); this._shapeMiniature = new Shape(); this._shapeMiniature.x = 600; this._shapeMiniature.y = 400; this.addChild(this._shapeMiniature); stage.addEventListener(MouseEvent.MOUSE_DOWN, evtStageMouseDown); stage.addEventListener(MouseEvent.MOUSE_UP, evtStageMouseUp); stage.addEventListener(KeyboardEvent.KEY_DOWN, evtStageKeyDown); } // ----------------------------------------------------------------------------------- // EVENEMENTS // ----------------------------------------------------------------------------------- private function evtStageMouseDown(event:MouseEvent):void { if ( this._path.data.length >= MAX_LIGNES ) { return; } this.graphics.moveTo(this.mouseX, this.mouseY); this._path.commands.push(1); this._path.data.push(this.mouseX, this.mouseY); this._txCode.appendText("C = 1 : " + this.mouseX + " x " + this.mouseY + "\n"); stage.addEventListener(MouseEvent.MOUSE_MOVE, evtStageMouseMove); } private function evtStageMouseUp(event:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, evtStageMouseMove); } private function evtStageMouseMove(event:MouseEvent):void { if ( this._path.data.length >= MAX_LIGNES ) { return; } this.graphics.lineTo(this.mouseX, this.mouseY); this._path.commands.push(2); this._path.data.push(this.mouseX, this.mouseY); this._txCode.appendText("C = 2 : " + this.mouseX + " x " + this.mouseY + "\n"); } private function evtStageKeyDown(event:KeyboardEvent):void { switch (event.keyCode) { case Keyboard.SPACE : trace("données = " + this._path.data.length); var t:uint = getTimer(); // recreer le dessin a partir des données GraphicsPath var stroke:GraphicsStroke = new GraphicsStroke(THICKNESS); stroke.fill = new GraphicsSolidFill(COLOR); var drawing:Vector.<IGraphicsData> = new Vector.<IGraphicsData>(); drawing.push(stroke, this._path); this.graphics.drawGraphicsData(drawing); trace("temps drawGraphicsData = " + (getTimer() - t)); t = getTimer(); // pareil mais en miniature et en utilisant drawPath aprés modification des // données GraphicsPath var tbPos:Vector.<Number> = new Vector.<Number>(); var nbPos:uint = this._path.data.length; for (var i:int = 0; i < nbPos; i++) { tbPos[i] = i % 2 ? this._path.data[i] / 3 : (this._path.data[i] - 100) / 3.5; } this._shapeMiniature.graphics.lineStyle(THICKNESS, COLOR); this._shapeMiniature.graphics.drawPath(this._path.commands, tbPos); trace("temps drawPath + boucle = " + (getTimer() - t)); break; case Keyboard.ENTER : // effacer les données this._txCode.text = ""; this._path = new GraphicsPath(new Vector.<int>(), new Vector.<Number>()); case Keyboard.DELETE : // effacer le dessin this.graphics.clear(); this.graphics.lineStyle(THICKNESS, COLOR); this._shapeMiniature.graphics.clear(); break; } } } }
![]()
Même avec un grand nombre de données a dessiner/modifier, on remarque que l’exécution est trés rapide.
Imaginons un forum un Flash ou n’importe quel autre interface, on pourrait donc stocker en externe (XML/DB/..) la définition visuel de tous les composants afin d’ajouter la possibilité de créer/modifier un thème graphique de A à Z ![]()
c’est trés plaisant !
Pour ceux qui ont installés FlashTracer dans Firefox, vous pouvez voir le trace du Flash qui affiche le nombre de données et le temps en milliseconde que prend les 2 types de dessin quand vous appuyez sur espace.
Le drawGraphicsData sur un le Vector comportant 10000 lignes (ce qui correspond quasiment au même nombre de ligne a dessiner), est executé en 1ms environ.
Concernant les nouveaux tableaux typés Vector, je m’attendais a des performances bien supérieur a un Array ou un Object, j’ai été décu ..
Suivant ce qui est stocké dans le Vector, on peut arriver a des performances inférieur a un Array 8-O, en stockant String par exemple, par contre avec uint et int les performances sont intéressantes.
![]()