Spark Icon Button with Gradient effects and Filter animation, colorized by styles. Flex 4 (Gumbo)
Keywords: advanced selectors, animate, AnimateColor, button, css, effects, Gradient, Icon, Pseudo, Selectors, Spark, styles, Transitions
update: Check this example for a more advanced and generic approach
Here’s an example of a Spark Icon Button done in Flex 4. There are smooth transitions on the background gradient between the up and over states. From the over state to the down state the shadows are removed smoothly. Each button has a different base color.
Click here for a demo.
Apart from the new skinning architecture there are a couple of aspects that make defining the look and feel of Spark Components easy:
- Transitions and effects that look up the values in the states
- Pseudo-Selectors for component-states, as well as id- and descendant selectors
- Enhanced states with group states.
- Colorization and exclusion
Transitions & effects
In this example the skin defines some transitions. There are AnimateColor effects that work on the gradient entries. There’s no special configuration involved, since the default-property that AnimateColor works on is… color . On the GradientEntry object there is a property for color. Flex automatically looks up the color values from the referenced states on the gradient entries.
In the states declarations there is an additional stateGroups ‘overStates‘ defined, that is referenced by the gradient entries. So there’s no need to explicitly define the colors for every state.
<s:states> <s:State name="up" /> <s:State name="over" stateGroups="overStates"/> <s:State name="down" stateGroups="overStates" /> <s:State name="disabled" /> </s:states> . . . <s:Transition fromState="up" toState="over" autoReverse="true" > <s:AnimateColor targets="{[ge1, ge2, ge3, ge4]}" duration="250" /> </s:Transition> <s:Transition fromState="over" toState="up" autoReverse="true" > <s:AnimateColor targets="{[ge1, ge2, ge3, ge4]}" duration="750" /> </s:Transition> . . . <s:fill> <s:LinearGradient x="32.019" y="0.5" scaleX="25.5708" rotation="90"> <s:GradientEntry id="ge1" color="#c0c0c0" color.overStates="#ffffff" ratio="0"/> <s:GradientEntry id="ge2" color="#939393" color.overStates="#e3e3e3" ratio="0.5"/> <s:GradientEntry id="ge3" color="#7e7e7e" color.overStates="#cecece" ratio="0.5"/> <s:GradientEntry id="ge4" color="#6a6a6a" color.overStates="#bbbbbb" ratio="1"/> </s:LinearGradient> </s:fill>
There are also Animate effects that work on the strength of the DropShadowFilters. The SimpleMotionPath entries tell the Animate effect to work on the strength property. Note that there are no values defined on the effects & properties of the transitions. Flex automatically looks up the start and target values from the referenced states.
<s:Transition fromState="over" toState="down" autoReverse="true" > <s:Animate duration="150" targets="{[dsfBg, dsfSymbol]}" > <s:SimpleMotionPath property="strength" /> </s:Animate> </s:Transition> <s:Transition fromState="down" toState="*" autoReverse="true" > <s:Animate duration="150" targets="{[dsfBg, dsfSymbol]}" > <s:SimpleMotionPath property="strength" /> </s:Animate> </s:Transition> . . . <s:filters> <s:DropShadowFilter id="dsfBg" alpha="0.5" blurX="0" blurY="0" distance="1" strength="1" strength.down="0" /> </s:filters> . . . <s:filters> <s:DropShadowFilter id="dsfSymbol" blurX="0" blurY="0" distance="1" strength="1" strength.down="0"/> </s:filters>
Now, the buttons have a subtle effect when the mouse is rolled over and pressed: The gradient colors get lighter and the Shadows disappear giving the impression that the button is pressed.
Styles. Pseudo-, Type-, Id- & Class-Selectors
We defined the gradients in grayscale. What when we want colored buttons? No need to change the gradients. Flex automatically colors the components based on the baseColor style. We can set the baseColor for each state using pseudo selectors. Here’s an example of how to style the button that shows all of the selector types (id-, type- and class-selectors):
@namespace mx "library://ns.adobe.com/flex/halo"; @namespace s "library://ns.adobe.com/flex/spark"; /* * Using ID selectors with compund selectors (type and class selectors) * to define the appearance of the buttons */ /* Define normal state styles on spark button type inside a desc container */ #desc s|Button { skinClass: ClassReference('AHSimpleIconButtonSkin'); baseColor: "0x505050" ; /* Do not use black black; /*"0x56d9e5";*/ color: #FFFFFF; } /* Define over states styles on spark button type inside a desc container */ #desc s|Button:over { baseColor: "0x97CD20"; } /* Define down states styles on spark button type inside a desc container */ #desc s|Button:down { baseColor: "0xa0d828"; } /* compound. override the over state of the button in element desc for class styleClass blueButton */ #desc .blueButton:over { baseColor: "0x56d9e5"; } /* compound. override the down state of the button in element desc for class styleClass blueButton */ #desc .blueButton:down { baseColor: "0x56d9e5"; } /* compound. override the over state of the button in element desc for class styleClass redButton */ #desc .redButton:over { baseColor: "0xd52A03"; } /* compound. override the down state of the button in element desc for class styleClass redButton */ #desc .redButton:down { baseColor: "0xE53A13"; } . . . <s:HGroup id="desc" horizontalCenter="0" verticalCenter="0" verticalAlign="middle" gap="5"> <s:Button label="Green" useHandCursor="true" buttonMode="true" /> <s:Button label="Blue" useHandCursor="true" buttonMode="true" styleName="blueButton"/> <s:Button label="Red" useHandCursor="true" buttonMode="true" styleName="redButton"/> </s:HGroup>
Colorization & Exclusion
By setting the baseColors for different states, Flex will colorize the component accordingly. A dark grey in the up-state, a color in the over state and a lighter color in the down state.
The bad thing is that everything gets colorized. The good thing is that you can overwrite a function on SparkSkin to exclude elements from being colorized. We only want the background gradient to get colorized, so lets exclude the other elements from colorization:
<fx:Script> <![CDATA[ /* Define the skin elements that should not be colorized. exclude symbol and text group */ static private const exclusions:Array = ["symbol", "textGroup"]; /** * @copy spark.skins.SparkSkin#colorizeExclusions */ override public function get colorizeExclusions():Array {return exclusions;} ]]> </fx:Script> . . . <!-- The group with the symbol with a shadow applied to. In a group for colorization exclusion --> <s:Group id="symbol" verticalCenter="0" left="7" top="9" right="7" bottom="7"> <s:filters> <s:DropShadowFilter id="dsfSymbol" blurX="0" blurY="0" distance="1" strength="1" strength.down="0"/> </s:filters> <s:Path winding="nonZero" data="M12.6924 0L5.76855 6.92383 2.30762 3.46191 0 5.76855 3.46191 9.23145 5.76855 11.5391 8.07617 9.23145 15 2.30762 12.6924 0Z" > <s:fill> <s:SolidColor color="#ffffff"/> </s:fill> </s:Path> </s:Group>
There is a group with an id ’symbol’ that is referenced in the exclusion array. Do the same for the label element.
Here’s a test and here’s the source (sdk 4.0.0.7282)
Source updated to Flex 4 release sdk.
Similar Posts
Shiny Gumbo Toggle-Buttons. Using Tint and Animate effects in skins.
Advanced FXG Spark Icon Buttons with one generic skin in Flex4 (Gumbo)
Custom PopUp Rating Component in Spark Flex 4 (Gumbo)
Custom Spark CheckBox Component in Flex 4 (Gumbo)
Custom Component in Flex 4 (Gumbo). A Knob Button - part 1.

June 18th, 2009 at 11:12 pm
Great Post!
I came across this post when I was digging my own similar post about creating an icon button:
http://www.themorphicgroup.com/blog/2009/06/18/how-to-create-a-spark-icon-button-and-skin/
I would love to get any input or thoughts from you.
June 18th, 2009 at 11:13 pm
Oh, I guess I should mention one thing different with my approach is you can declare different icon images for different mouse states.
June 20th, 2009 at 8:02 pm
Ben,
I had a look at your example and think it is very clean and useful. Having different icons per states makes sense.
I did something similar here, using FXG-based icons.
http://www.hulstkamp.com/2009/06/20/advanced-fxg-spark-icon-buttons-with-one-generic-skin-in-flex4-gumbo/439
November 4th, 2009 at 3:03 am
[...] AH: Spark Icon Button with Gradient effects and Filter animation … [...]
January 22nd, 2010 at 8:57 pm
Hi Andy,
I was wondering how did you get the values for the path data. Those numbers are fractional values and it doesn’t look like you spent your time trying to find them by trial and error.
Thanks.
February 2nd, 2010 at 1:23 am
Anshul
AI has an FXG-Export
April 6th, 2010 at 8:38 pm
Any idea why the baseColor css property does not work in the flex 4 release sdk with your exact code?
April 7th, 2010 at 7:21 pm
nobody
thanks for pointing this out. Check this post .
May 6th, 2010 at 11:41 pm
[...] http://www.hulstkamp.com/2009/06/18/spark-icon-button-with-gradient-effects-and-filter-animation-col... [...]
June 18th, 2010 at 9:52 am
Help! i cannot find SimpleText in my Flex SDK 4.0.0.14159, any idea?
June 18th, 2010 at 10:22 am
gembin
SimpleText has become Label in the final release of F4.
Check the updated comps here.
September 19th, 2011 at 4:57 pm
[...] it is not 100% identical. If you want to improve it here is source code. I want to recommend this example for beginners and for developers who are migrating from MX to [...]
November 26th, 2011 at 6:24 pm
Hi great work..:), I tried doing it with a graphic with a path but the transition happens instantly, any ideas what the issue may be?