Thursday, March 15, 2012

Flex: Drawing Shapes in Flex

Every single shape in this world are made out of simple shapes like circles, triangles and squares. Therefore, there might be situations where a coded shape or graphic can turn out to be much much more useful and flexible and lighter (in terms of the files size) than a normal image file(*.png, *.jpg, etc...). As for this week, I'm going to show you the steps in creating a simple Shape in flex.

Source codes for the main application
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
    layout="absolute"
     creationComplete="creationCompleteHandler(event)">
 <mx:Script>
  <![CDATA[
   import com.shapes.ShapeClass;
   
   import mx.core.UIComponent;
   import mx.events.FlexEvent;
   
   //Array to store a list of blue colors
   private var blueColorArray:Array = [0xFFFFFF, 0xEEEEFF, 
    0xDDDDFF, 0xCCCCFF, 0xBBBBFF, 0xAAAAFF,
    0x8888FF, 0x6666FF, 0x4444FF, 0x2222FF];
   private var blueColorCount:int = 0;
   
   //Array to store a list of black colors
   private var blackColorArray:Array = [0xFFFFFF, 0xCCCCCC, 
    0x999999, 0x666666, 0x333333, 0x000000];
   private var blackColorCount:int = 0;   
   
   //A timer that will be used to draw the Shapes
   //over and over again.
   private var timer:Timer = new Timer(100,0);
   
   protected function creationCompleteHandler(event:FlexEvent):void
   {
    timer.addEventListener(TimerEvent.TIMER, executeTimer);
    executeTimer();
   }
   
   //Function that will return an array of colors
   //based on the starting point, so that the Shapes
   //will appear to be animating
   private function getBlueColorsArray(tempColorArray:Array, 
            tempCount:int):Array
   {
    var tempArray:Array = new Array();
    for(var i:int = tempCount; 
     i < tempColorArray.length; i ++)
    {
     tempArray.push(tempColorArray[i]);
    }
    for(i = 0; i < tempCount; i ++)
    {
     tempArray.push(tempColorArray[i]);
    }
    return tempArray;
   }
   
   //This function will be trigger once the timer has 
   //run finish a cycle.
   private function executeTimer(event:Event = null):void
   {
    //Stops the timer first.
    if(timer.running)
    {
     timer.stop();
    }
    //Remove all the graphics and draw a new Shape
    layer1.removeAllChildren();
    layer1.addChild(ShapeClass.drawCircleTower(50, 
     getBlueColorsArray(blueColorArray, blueColorCount)));
    //Remove all the graphics and draw a new Shape
    layer2.removeAllChildren();
    layer2.addChild(ShapeClass.drawCircleTower(layer2.width, 
     getBlueColorsArray(blackColorArray, blackColorCount)));
    //As the shape is position at (0,0) we will need to
    //reassign the position of the shape everytime we draw
    //it so that the shape will always appear on the point
    //(10,10).
    layer3.removeAllChildren();
    var tempDisplayObject:DisplayObject;
    tempDisplayObject = layer3.addChild(
     ShapeClass.drawCircle(layer3.width/2,
     blueColorArray[Math.round(Math.random()*
      (blueColorArray.length - 1))],
     true));
    tempDisplayObject.x = layer3.width/2;
    tempDisplayObject.y = layer3.height/2;
    blueColorCount ++;
    if(blueColorCount >= blueColorArray.length)
    {
     blueColorCount = 0;
    }
    blackColorCount ++;
    if(blackColorCount >= blackColorArray.length)
    {
     blackColorCount = 0;
    }
    timer.start();
   }
   
  ]]>
 </mx:Script>
 <mx:Canvas width="100%" height="100%">
  <mx:VBox width="100%" height="100%" 
     verticalAlign="middle" 
     horizontalAlign="center">
   <mx:Canvas id="layer1"/>
  </mx:VBox>
  <mx:Canvas width="100%" height="100%">
   <mx:Canvas id="layer3"  
        width="150" height="150"
        top="10" left="10"/>
   <mx:Canvas id="layer2" 
        width="100" height="100"
        right="10" bottom="10"/>
  </mx:Canvas>
 </mx:Canvas>
</mx:Application>

Source codes for a Shape Class that I have written:
package com.shapes
{
 import flash.display.Shape;
 
 import mx.core.UIComponent;

 public class ShapeClass
 {
  public function ShapeClass()
  {
  }
  
  /**
   * 
   * @param radius - radius of the circle 
   * @param color - fill color of the circle
   * @param createView - do you need this function
   * to return a view that can be added to any view
   * or a Shape using (0,0) as the midpoint.
   * @return either a Shape or a View
   * 
   */  
  public static function drawCircle(radius:int, 
            color:uint,
            createView:Boolean = false):*
  {
   var shape:Shape = new Shape();
   shape.graphics.beginFill(color,1);
   shape.graphics.drawCircle(0,0,radius);
   shape.graphics.endFill();
   if(createView)
   {
    var tempUI:UIComponent = new UIComponent();
    tempUI.addChild(shape);
    return tempUI;
   }else{
    return shape;
   }
  }
  
  /**
   * 
   * @param radius - radius of the circle 
   * @param colors - an array of colors of this Shape
   * @return a view that shows a sequence of Circles
   * using (0,0) as the midpoint.
   * 
   */  
  public static function drawCircleTower(radius:int, 
              colors:Array):*
  {
   var length:int = colors.length;
   var diff:Number = radius / length;
   var tempUI:UIComponent = new UIComponent();
   var tempShape:Shape = null;
   for(var i:int = 0; i < length; i ++)
   {
    tempShape = drawCircle(radius - (i * diff),
     colors[i]);
    tempUI.addChild(tempShape); 
   }
   return tempUI;
  }
 }
}
* Click here to view the demo of this example.
^ Click here for the source files of this demo.

No comments:

Post a Comment