. .
Feb 2011

Programmatic drawing of backgrounds in Flex

In order to create a “stripes” look for a component without juggling graphics, i wanted to implement my own fill. Actually, it turned out to be quite simple to do:

package de.viaboxx.flexClient.utils.ui {
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import mx.graphics.IFill;
 
/**
 * Implements a striped fill with customizable colors and stripe width and angle.
 */
public class StripedFill implements IFill {
    /**
     * The width of the stripes, in pixels. Defaults to 10 pixels.
     */
    public var stripeWidth:int = 10;
 
    /**
     * The angle in which the stripes are drawn in degrees. 0 = top to bottom, 90 = left to right.
     * Defaults to 45.
     */
    public var angle:uint = 45;
 
    private const black:uint = 0x000000;
    private const yellow:uint = 0xFFCC00;
 
    /**
     * Colors used for stripes. The stripes are drawn in the colors given here, in the same order they are defined
     * inside this array.
     */
    public var colors:Array = [black,yellow];
 
    private static var matrix:Matrix = new Matrix();
 
    public function StripedFill() {
        super();
    }
 
    /**
    * @inheritDoc
    */
    public function begin(target:Graphics, targetBounds:Rectangle, targetOrigin:Point):void {
        matrix.identity();
        matrix.rotate((angle * Math.PI) / 180);
        var bitmap:BitmapData = new BitmapData(stripeWidth * colors.length, targetBounds.height, false);
        for (var colorIndex:uint = 0; colorIndex < colors.length; colorIndex++) {
            var singleColorRectangle:Rectangle = new Rectangle(colorIndex * stripeWidth, 0, stripeWidth, targetBounds.height);
            bitmap.fillRect(singleColorRectangle, colors[colorIndex]);
        }
        target.beginBitmapFill(bitmap, matrix, true, true);
    }
 
    /**
    * @inheritDoc
    */
    public function end(target:Graphics):void {
        target.endFill();
    }
}
}

To do things like this, you can build your own implementation of mx.graphics.IFill. The interface defines just two methods. The real twist implementing the fill was to draw into a flash.display.BitmapData object and use flash.display.Graphics#beginBitmapFill to use the self-drawn graphic as fill.

I wanted the angle the stripes are being drawn to be configurable. This kind of thing is done using a matrix-based transformation, so flash.geom.Matrix#rotate is a good fit here. Just pass the rotation matrix when calling beginBitmapFill and there you go!

Using the fill is a snap:

...
<s:Rect
  width="250"
  radiusX="6"
  radiusY="6"
  y="0"
  x="0"
  height="290">
    <s:fill>
        <util:StripedFill
          stripeWidth="10"
          angle="45"
          colors="{[0x000000,0xFFCC00]}">
        </util:StripedFill>
    </s:fill>
</s:Rect>
...
Making things like this easy is one of the nice sides of Flex.