Here’s 5 3D Layouts for Flex 4
I spent some time converting the OpenFlux 3D layouts to Flex 4 last week and have attached the example with source code. This includes CoverFlow (horizontal and vertical), Carousel, Spiral and Time Machine. I also included one which was created when I screwed up the CoverFlow layout but I thought it looked cool so I hit Save As and named it AwesomeLayout.
Overall I was really happy with how quickly I could get these working with Flex 4. It wasn't quite as painful as I originally thought and I'll discuss the differences below.
View the Example
View the Source Code
ILayoutElement
In Flex 4, UIComponent implements ILayoutElement which provides you a bunch of methods to manage the layout of each child. For 2D layouts you would use element.setLayoutBoundsSize( width, height, postLayoutTransform ) to set the size and element.setLayoutBoundsPosition( x, y, postLayoutTransform ) to set position.
OpenFlux instead allows you to set x, y, width, height, z, rotationX, rotationY, rotationZ directly to a token which is used to animate the child to its new position/size.
Matrix3D
With OpenFlux, you set the z, rotationX, rotationY, rotationZ properties directly. With Flex 4 you instead use element.setLayoutMatrix3D( matrix, postLayoutTransform ). Instead of passing in the above properties it instead expects an instance of Matrix3D. This was my first use of Matrix3D and Vector3D (FP10 classes) and had no idea what I was doing until I looked at the example Flex 4 WheelLayout
A common approach would be to first set the initial 3D coordinates of the child, next apply any rotation and third center the child in the container. Below is the Matrix3D code for AwesomeLayout:
var matrix:Matrix3D = new Matrix3D();
matrix.appendTranslation( elementWidth * -( selectedIndex - i ), elementHeight / 2, 0 );
matrix.appendRotation( Math.abs( selectedIndex - i ) * 2, Vector3D.Y_AXIS );
matrix.appendTranslation( width / 2, height / 2, 0 ); // center element in container
element.setLayoutMatrix3D( matrix, false );
maintainProjectionCenter
FP10 adds a perspectiveProjection property to the Transform class which works similar to a camera in Away3D. By default, the prespectiveProjection is set to the top left but for my layouts I need it to be the center of the container. This is easily done with the following code:
var pp:PerspectiveProjection = new PerspectiveProjection();
pp.projectionCenter = new Point(container.width / 2, container.height / 2);
container.transform.perspectiveProjection = pp;
Since wanting center projection is so common though, Flex 4 made this even easier by adding a maintainProjectionCenter flag to UIComponent. When the layout is attached to a container, I simply override the setter and set this property to true.
layer
Another pain in the butt with FP10 is that the z property has nothing to do with the z-index of the DisplayObject. What that means is even though the DisplayObject appears to be further away and smaller, it will still be in front of closer DisplayObjects unless you update it's position in the display list.
Flex 4 solves this by adding a layer property to UIComponent. For the List component for example, this allows you to specify a different display list index for the item renderer compared to where it is located in the data provider. You simply set the layer property for each element (based on its z property ideally) and if required call container.invalidateLayering()
OpenFlux handles this automatically after the layout is done setting the position of each child.
Animation?
One question I'm hoping someone has a decent answer to is regarding animating the size/position of child elements. For example, if I switch layouts I want the children to be tweened to their new positions. This is easy to do with OpenFlux but I have no idea how to do it with Flex 4. I know Flex 3 introduced a dataChangeEffect but this seems to have disappeared with the Flex 4 List component.
What next?
So, I only implemented the very basics of the layout. Next steps would be to add support for measure, scrolling and virtualization. I've included a LayoutBase3D class which handles common 3D tasks. I'd love to see what layouts others come up with and think it would be cool to start a Flex 4 Layouts open source project.
Feel free to write any questions in the comments.

June 16th, 2009 - 08:00
Love it Ryan!
Its great to see the work on all the new layout features paying off. These layouts are beautiful.
Ely.
June 16th, 2009 - 09:37
Hey Ryan,
These are cool!
On animation and scrolling:
Scrolling – When I created the WheelLayout, I had to override a couple of methods:
1. To abstract the scrolling in the horizontal direction – LayoutBase.updateScrollRect()
2. To implement the step/page on the scrollbar snapping to the elements – LayoutBase.getHorizontalScrollPositionDelta()
3. To be able to know how much to scroll to get a particular item in view – LayoutBase.getScrollPositionDeltaToElement()
4. To make sure that when the scrollPosition changes I rerun the layout – LayoutBase.scrollPositionChanged()
Once I had scrolling, the animation was very easy, I simply animated the scrollPosition from the current one to the scroll position for the element that’s clicked.
-Evtim
June 16th, 2009 - 09:44
Hi Evtim,
Yes, I plan to do the same with scrolling. For now I could do the same by animating the index property of my layouts.
But what about animating children when changing layouts? That would need to be handled by the Flex framework.
See my old OpenFlux example to see what I mean:
http://www.bobjim.com/2008/04/04/updated-plexiglass-openflux-3d-example/
Ideally setLayoutBoundsPosition/Size/Matrix methods would handle animation for you.
Ryan
June 17th, 2009 - 11:02
Hi Ryan, yup I see what you mean. The Flex framework doesn’t provide support for automatic animation of the children upon layout/container changes.
For animations within the same layout we recommend animating layout properties to drive the elements on screen.
Layout switching animations are not supported out of the box.
For layout switching with simple cases where you have the same elements showing in both states you can write a small action-script code to animate the elements’ transforms between the two states (run layout in src state, capture src values, run layout in dst state, capture dst values, animate between the two).
For cases involving lists, item renderers and virtualized layouts, things get quite complicated as the item renderer recycling and creation has the possibility to have the item renderer not exist in one of the states or correspond to a different item in the second state.
June 20th, 2009 - 19:02
There’s no way you’re going to use Flex 4 over OpenFlux! OpenFlux is WAY better. Full 3D support, full animation support, way easier to customize.
January 7th, 2010 - 05:43
@Ryan Campbell
The Spiral Layout might look very nice animated