tile or repeat an image into a flex application background

UPDATE: There is a revised version of this post here, which you might find more accessible. It also includes a tile into the background of a Canvas.

I’ve only been using Flex for a few weeks via the Flex Builder Beta for the Mac. While I am really impressed with the ease of use of the framework, and now something of a convert, I was suprised by the apparent inability to tile (or repeat) an image over the background of the Application.

I tried a number of approaches which I now look back on as naive. I haven’t at this point managed to find a documented solution by googling. Though as responses to this post show (update: source now published), there seems to be interest in finding a solution.

So here is one solution. I don’t claim this to be ‘best practice’. Far from it. But it works, and will suffice for me until I am more familiar with Flex.

  1. Locate your flex installation, then Flex SDK 2/frameworks/source
  2. From here navigate the package structure to mx.skins.halo
  3. Duplicate file “ApplicationBackground.as” to a suitable location within your project file structure. In my case saved to ‘{projectroot}/com/ct/skins”
  4. Edit your local copy as per the following notes

Adjust the package detail

In my case the package line now reads:

package com.ct.skins

Add some imports

We need the following import lines to access the bitmap data:

import flash.display.Bitmap;
import flash.display.BitmapData;

Remove the version include

Because we are working outside the structure of the halo skin collection, we no-longer need or want the following line:
include "../../core/Version.as";

Embed the image and declare some variables

In this case I am embedding the image at compile time:

[ Embed( source='/assets/BackgroundLines.png' ) ]
private var backgroundImageClass :Class;
private var backgroundImage :Bitmap;
private var backgroundBitmapData :BitmapData;

Modify the constructor

In our constructor, after the call to ‘super()’ we need to get the bitmap data of the image into the backgroundBitmapData variable, we do this by first creating a Bitmap instance of the embedded image in backgroundImage, then drawing the data into backgroundBitmapData:

backgroundImage = new backgroundImageClass();
backgroundBitmapData
= new BitmapData( backgroundImage.width, backgroundImage.height );
backgroundBitmapData.draw( backgroundImage );

Clear out and replace the content of updateDisplayList

The only line we need keep is the super call. Everything else can be replaced with the following 4 lines:

var g:Graphics = graphics;
g.clear();
g.beginBitmapFill( backgroundBitmapData );
g.drawRect(0,0,w,h);

Now we just need to apply it.

All we need to do is point the borderSkin attribute of the mx:Application tag to this new skin. In my case the attributes of mx:Application look like this:

xmlns:mx ="http://www.adobe.com/2006/mxml"
frameRate ="36"
layout ="absolute"
borderSkin ="com.ct.skins.ApplicationBackground"

Bob’s your uncle!

I’d appreciate comments on a better practice approach.

Further reading:

10 Comments

  1. micmac says:

    Nice article.
    I’m a recent advocate of Flex myself and was disappointed to discover no tiling feature.
    I do have one question. How would i go about restricting the tiling to the x-axis? At the moment it is tiling both x and y axis.

  2. creacog says:

    Well it is really a hard-coded sticking plaster approach, and so is this answer to your question…
    The line which governs the region into which the bitmap is pasted and repeated is this one:
    g.drawRect(0,0,w,h);
    which currenty represents the whole of the canvas. To effectively repeat-y you could modify the line to:
    g.drawRect(0,0,backgroundImage.width,h);
    To repeat-x:
    g.drawRect(0,0,w,backgroundImage.height);

  3. Funny I had the same approach.

    http://labs.flexcoders.nl/?p=16

    See sample (view source under contextmenu)

  4. diny says:

    i would like to load image in my application… how it is possible???

    Thanks in advance
    Diny

  5. Thanks, worked perfectly, one thing to note:

    You can then specify the borderSkin property in a css file instead of hardcoding it:

    Application
    {
    borderSkin: ClassReference(‘com.ct.skins.ApplicationBackground’);
    }

  6. sana says:

    good but an error does not resolve at these lines

    backgroundImage = new backgroundImageClass();

    backgroundBitmapData
    = new BitmapData( backgroundImage.width, backgroundImage.height );
    backgroundBitmapData.draw( backgroundImage );

  7. creacog says:

    @sana: It would help me understand if you detailed the error you are seeing.
    Alternatively take a look at the updated version of this blog-post which includes a working sample… tile or repeat an image into a flex application background II

  8. Monal says:

    Thank you very much!
    This was immensely helpful.

Leave a Reply