The Canvas layout container. We all know it, we all love it. Lets us place our components wherever we like. Such a good sport.
But the one aspect I dislike about the Canvas container is the lack of a background gradient. Why should buttons have all the fun?
After reading through the source code for the Canvas container and Button control, I realized creating a Canvas with a background gradient would be pretty easy, so long as I was willing to tinker around with the drawing API.
Which I was.
So how did I do it? I extended the Canvas container in a new AS3 class, and overrode the updateDisplayList() method. That’s it.
The beauty of this is that it doesn’t mess with the layout of the child components in the container. It just makes the background a whole lot prettier.
Sample code for the GradientCanvas:
|
package { import mx.containers.Canvas; import mx.styles.StyleManager; import mx.utils.ColorUtil; public class GradientCanvas extends Canvas { override protected function updateDisplayList (w : Number, h : Number) : void { super.updateDisplayList (w, h); // retrieves the user-defined styles var fillColors : Array = getStyle (“fillColors”); var fillAlphas : Array = getStyle (“fillAlphas”); var cornerRadius : Number = getStyle (“cornerRadius”); // converts the fill colors to RGB color values StyleManager.getColorNames (fillColors); // ready to draw! graphics.clear (); // draws the gradient drawRoundRect (0, 0, w, h, cornerRadius, fillColors, fillAlphas, verticalGradientMatrix (0, 0, w, h)); } } } |
You’ll notice in the code that I only check for the fillColors, fillAlphas and cornerRadius styles in my component. That’s all I really needed for my GradientCanvas container, but if you wanted to add support for borders and shadows you would simply add the styles and draw them as well.
Piece of pie.

19 comments
Comments feed for this article
March 6, 2008 at 12:07 am
burnhh
Hi there,
is there a way in flex to move the values for fillColors and fillAlphas into a CSS style sheet? AFAIK assigning arrays within a style sheet is not allowed and does not seem be be compiled though setStyle works flawlessly.
Regards, burn
March 6, 2008 at 8:31 am
Nick Schneble
Hey Burn,
The container is already pulling those array values from the CSS.
The getStyle() methods in GradientCanvas actually pull properties directly from whatever styles have been set on the container.
For example, getStyle (“fillColors”) pulls the “fill-colors” CSS style from wherever the property has been set in the container’s style lookup chain.
Here’s a sample bit of CSS, including how to specify arrays of values for fillColors and fillAlphas:
GradientCanvas
{
fill-colors: #FFFFFF, #000000;
fill-alphas: 1.0, 0.5;
corner-radius: 0;
}
March 6, 2008 at 10:44 pm
burnhh
and again just what i needed. thx nick!
it seems like the flex compiler internally does not care about case sensitivity or whether to use dashes within a style declaration (e.g. fill-alphas vs. fillAlphas). a bit strange but good to know…
burn
August 14, 2008 at 7:33 am
lynda0119
i can’t see the codes in http://userflex.wordpress.privatepaste.com/19O9zv4j8c
can you please repost?
August 14, 2008 at 7:39 am
Nick Schneble
Sorry about that – most of the code snippets I created on PrivatePaste were accidentally deleted when the developer added a new feature to ‘expire’ content.
I’ll repost the sample code shortly!
August 14, 2008 at 7:44 am
lynda0119
am so new not sure how to apply that to my css.
August 14, 2008 at 7:48 am
lynda0119
Nick, also can you repost the Gradient Canvas example for me please. http://userflex.wordpress.privatepaste.com/560JC0KMmm
August 14, 2008 at 7:50 am
Nick Schneble
No worries – I’ll update them both in a few minutes!
August 14, 2008 at 8:15 am
Nick Schneble
Updated!
August 14, 2008 at 8:48 am
lynda0119
in my CSS page, should i set the background: ClassReference (“GradientCanvas”)?
August 14, 2008 at 8:52 am
Nick Schneble
You can set the background in CSS like this:
GradientCanvas
{
background-color: #0000FF;
}
Alternatively, if you don’t want to use the same background color for all your GradientCanvas containers, then you can set it for a single style:
.myCustomStyle
{
background-color: #0000FF;
}
August 14, 2008 at 9:38 am
lynda0119
i have multiple tabs that required multiple different color setting. how do I do that in the css?
August 14, 2008 at 10:43 am
Nick Schneble
I posted about how to do that here:
http://userflex.wordpress.com/2008/02/14/skin-tabnavigator-tabs/
December 15, 2008 at 10:15 am
rajeshbhadra
If I load a skin swf file for a particular component using StyleManager.loadStyleDeclaration(path,true), it loads up the swf file and applies the skin assets(up,over and down states) to a particular component. But at the same time it also breaks up the system font color. The textarea’s font color changes to white and also the text color of the button changes to white. Can you help ? I am using flex builder 3 and sdk version is 3.0.0 along with Flash Player version 9.0.124.
January 6, 2009 at 3:30 pm
jamesclinton
Hi Thanks this canvas. very useful. I am however having a problem which is dead simple to solve i think, but I’m new to Flex.
Bascially when compiling, I cannot find the styles. I have tried including them inline and in a css file, but no joy…can you help? Compile error is
“Syntax error. var fillAlphas : Array = getStyle (?fillAlphas?);”
If I hard code in the values it works file.
January 7, 2009 at 10:39 am
Nick Schneble
@rajeshbhadra
Can you post the CSS for your style SWF?
When you load a new style declaration it will override any previously loaded styles, so it’s likely that something in your style SWF is setting those colors to white.
January 7, 2009 at 10:46 am
Nick Schneble
@jamesclinton
How did you include them in your CSS file? For the getStyle() method to work, you need to have styles defined for that component.
For example, given the GradientCanvas component above, you would need to have something like the following in your CSS file:
GradientCanvas
{
fill-colors: #FFFFFF, #000000;
fill-alphas: 1.0, 1.0;
corner-radius: 0;
}
January 29, 2009 at 5:02 pm
ryanbbeard
Something to notice if you are getting 6 errors on lines 15,16, and 17 on GradientCanvas.as it’s because wordpress turns a programming quote ” into a quote you would see if you were actually quoting someone. I know this was an error for me for a good hour before I remembered this issue. And maybe what jamesclinton was having issue with. Great code tho
thanks
May 19, 2009 at 7:24 am
egroulx
Thanks for this code, really helpful. Here’s the metadata you need to add to the top of the class if you want to be able to set values as mxml attributes :
[Style(name="fillAlphas", type="Array", arrayType="Number", inherit="no")]
[Style(name="fillColors", type="Array", arrayType="uint", format="Color", inherit="no")]