Spark Icon Button with Gradient effects and Filter animation, colorized by styles. Flex 4 (Gumbo)

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.

Spark Icon Buttons with transitions

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.



Share/Save/Bookmark

11 Responses to “Spark Icon Button with Gradient effects and Filter animation, colorized by styles. Flex 4 (Gumbo)”

  1. Ben Bishop Says:

    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.

  2. Ben Bishop Says:

    Oh, I guess I should mention one thing different with my approach is you can declare different icon images for different mouse states.

  3. Andy Hulstkamp Says:

    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

  4. graphic design illustrator text effects | Ramblings of an Internet Addict Says:

    [...] AH: Spark Icon Button with Gradient effects and Filter animation … [...]

  5. Anshul Says:

    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.

  6. Andy Hulstkamp Says:

    Anshul

    AI has an FXG-Export

  7. nobody Says:

    Any idea why the baseColor css property does not work in the flex 4 release sdk with your exact code?

  8. Andy Hulstkamp Says:

    nobody

    thanks for pointing this out. Check this post .

  9. Flex 4 — Reusable Icon Button Skins « Everything Under The Sun Says:

    [...] http://www.hulstkamp.com/2009/06/18/spark-icon-button-with-gradient-effects-and-filter-animation-col... [...]

  10. gembin Says:

    Help! i cannot find SimpleText in my Flex SDK 4.0.0.14159, any idea?

  11. Andy Hulstkamp Says:

    gembin

    SimpleText has become Label in the final release of F4.
    Check the updated comps here.

Leave a Reply