Spark List with Zoom Effect

For a recent project  I needed to create a trivial image list with zoom effect for a spark based application. Image lists are commonly used for image galleries or menus, and Flex offers some UI components to quickly create and configure these generic lists, so I did not expect any difficulties.
I was wrong. Even though creating image lists became an almost trivial task, there are a few pitfalls and none of the samples posted by Adobe were clear enough to address them. After spending some time with tour-de-flex samples I managed to come up with a different working solution.

This is what I needed:

Basic Image List

First of all lets consider the options. A list can be created by either a DataGroup or a spark List. Both components can display a list based on data provider and item renderer, but there are a few differences, summarized here:

  1. List is skinnable, DataGroup is not.
  2. DataGroup is much lighter
  3. List provides  additional  functionality, namely selection and drag-drop

Since I needed the select functionality I decided to go with the List.

<s:List id="lst1"
          dataProvider="{sampleData}"
          itemRenderer="cc.ImageRenderer"
          rollOverColor="#cccccc" selectionColor="#eeee00"
          width="100%">
       <s:layout>
            <s:HorizontalLayout gap="4"/>
       </s:layout>
 </s:List>

The Item Renderer

Start with a basic renderer from a template: ‘New->MXML Item Renderer’. Add an image control as the main display object, and optionally some background. If you try to run you’ll get a list with static images.

<s:states>
    <s:State name="normal" />
    <s:State name="hovered" />
    <s:State name="selected" />
</s:states>
 
<s:Rect left="0" right="0" top="0" bottom="0">
    <s:fill>
        <s:SolidColor
            color.normal="0x808080"
            color.hovered="{getStyle('rollOverColor')}"
            color.selected="{getStyle('selectionColor')}"
            />
    </s:fill>
</s:Rect>
 
<mx:Image id="img"
          verticalAlign="middle" horizontalAlign="center"
          left="4" right="4" top="4" bottom="4" />

Note that I took advantage of the styles for selection and rollover colors.
Now we add the effect, using the postLayoutTransformOffsets property of the item renderer.

<!--       The Zoom effect      -->
<s:postLayoutTransformOffsets>
    <s:TransformOffsets id="tOffsets"
                        scaleX="1" scaleY="1"
                        scaleX.hovered="1.5" scaleY.hovered="1.5"
                        scaleX.selected="1.1" scaleY.selected="1.1" />
</s:postLayoutTransformOffsets>
 
<!--       Transitions          -->
<s:transitions>
    <s:Transition toState="hovered" autoReverse="true">
        <s:Animate target="{tOffsets}" duration="200">
            <s:SimpleMotionPath property="scaleX" />
            <s:SimpleMotionPath property="scaleY" />
        </s:Animate>
    </s:Transition>
    <s:Transition fromState="hovered" autoReverse="true">
        <s:Animate target="{tOffsets}" duration="200">
            <s:SimpleMotionPath property="scaleX" />
            <s:SimpleMotionPath property="scaleY" />
        </s:Animate>
    </s:Transition>
</s:transitions>

To make the scale work from the center, simply set transformX and transformY to half the size of the renderer. Run the code and see the nice zoom effect on rollover. Works nice overall, but there is one problem – since the items are scaled during the effect, the area for the list is based on the normal scale, clipping the oversized item on the edges of the list. Simply put, we need some more space between the list and its container – which brings us to skinning.

Skinning the list

The default skin for spark list is basically a DataGroup enclosed within a scroll component. Simply adding margins between the list and the scroller will not do – the images would still get clipped. We need to wrap the list in a group, so that clipping can be controlled. Replacing the scroller block with the following code will do the trick.

<!--- The Scroller component to add scroll bars to the list. -->
<s:Scroller left="0" top="0" right="0" bottom="0" id="scroller" >
 
    <s:Group left="0" top="0" right="0" bottom="10">
        <s:DataGroup id="dataGroup"
                     left="22" top="26" right="22" bottom="26"
                     itemRenderer="spark.skins.spark.DefaultItemRenderer">
        </s:DataGroup>
    </s:Group>
 
</s:Scroller>

Final Result

   

The demo app contains the three different lists to compare the effect of the skin and rederer.
Looking at the final result, we got a slightly modified skin for the list and the item renderer. Most of the effort went on skinning – not bad, considering the list itself and the effect are used almost out of the box.

3 thoughts on “Spark List with Zoom Effect

  1. Really excellent work! I’ve been struggling with exactly these issues as well. Thank you Thank you Thank you.

Comments are closed.