Monday, March 29, 2010

Custom Flex layout. Safari-like Top Sites

Maybe you are asking yourself "Why am I here?" Well the simple answer is here:


So what is this? It's a custom flex 4 layout that displays elements as in cylinder. The idea for it I got a long time ago when I saw Safari's Top Sites. Back then I managed to achieve this look and feel with flex using Papervision3D. But I didn't like the way I made it at all. So year later I have decided to try again. This time with the native 3D support of Flash Player 10 and the new layouting in Flex 4 it was quite intuitive and the most proper solution.


Enough talking lets see the real thing. So this is the Safari Top Sites that inspired me

And this is the result

You can see the Flex Top Sites application here and the source code here.

The logic of implementing a custom 3d layout I got from these posts of Ryan Campbell and Evtim Georgiev

The basic things are
  1. Create a class that extends LayoutBase
  2. On updateDisplayList position and transform the images
  3. Transforming elements(images) to look like they are in cylinder
    The idea here is to move the element in the back (translate over Z) and then rotate over the Y Axis
  4. Do the same for the other elements but rotate them by different angle and/or translate over Y
  5. Bring the images more in front (because the current look would be if we are in the center of cylinder)
The code for the last 3 is

var matrix:Matrix3D = new Matrix3D();
matrix.appendTranslation(-_columnWidth/2, 0, radius);
matrix.appendRotation(startDegree + degreesMove*j, Vector3D.Y_AXIS);
matrix.appendTranslation(width/2, (_rowHeight + _horizontalGap) * i ,-cameraPosition);
element.setLayoutMatrix3D(matrix, false);

Important thing here is
var pp:PerspectiveProjection = new PerspectiveProjection();
pp.projectionCenter = new Point(width/2, height/2);

element["transform"].perspectiveProjection = pp;

In short words when providing this when we rotate the element the point of the rotation will be the center of the screen (container).

The other things are just plain geometry calculations, like finding the radius, chord, arc of a circle. Really important thing is to imagine both 3D cylinder, 2D circle from top and 2D rectangle from front.

The TopSiteLayout.as provides also options to specify number of rows, columns, width of columns, height of columns, vertical and horizontal gap, although it works just fine if you let it calculate these values itself

And to finish with, I have added this reflection for the 4 images at the bottom. I am using WetFloorFilter from Gonta. It is really good and it is for Flex 4

var filter:WetFloorFilter = new WetFloorFilter();
filter.height = 100;
filter.alpha = 0.5;

BindingUtils.bindProperty(filter, "y", thumbnail, "height");

thumbnail.filters = [filter];

And basically that's all. You can download the custom layout from here.
Would really like to hear what you think

19 comments:

  1. Nice post. In the first matrix example is this just a picture or you are layouting several images??

    ReplyDelete
  2. wow that totally looks like safari! Great example...although it is better if I can click on all sites not just the first one

    ReplyDelete
  3. Thanks guys!

    @Peter these are 200 images (20 columns, 10 rows) to be exact that are added in a group, and the layout for the group is this custom layout. You can see the source: http://maverix7.appspot.com/files/MatrixTopSiteLayout/srcview/index.html

    @Deras I am aware of this problem. Actually you should be able to click on the other images but only with Flash Player 10.1 that is beta 3. It fixes the bug causing this.

    ReplyDelete
  4. yeah i saw the source code and indeed i should be able to click. Strange, atleast i hope the new flash player will fix it.

    ReplyDelete
  5. cant see the source code page

    ReplyDelete
  6. I am a total noob on this, I got the source zip file, how do I create the swf object which display all the sites I wanted? Could you please tell me in details?

    ReplyDelete
  7. Yeah after the last update I forgot to include the source. Check it out here http://maverix7.appspot.com/files/TopSites/srcview/index.html

    ReplyDelete
  8. Hi, Tony, I got the source now, thank you. However, I don't completely understand the logic here. For example how's your swf been generated? And how's the mxml works here. I am sorry for the lack of my knowledge, but your app seems to be really cool and I wanna use it for my website

    ReplyDelete
  9. Hey, thanks for saying it's cool! However questions like yours cannot be just answered, you should learn Flex/Flash. You can see the articles from http://training.obecto.com/ it is a great source for learning Flex

    ReplyDelete
  10. Thank you for providing me the link, I will start digging~ I know its always more meaningful to learn by myself than get the answer from others. Thanks again.

    ReplyDelete
  11. Hi, Tony, do I need to have a Adobe Flex or Flash Builder 4.5 to be able to run your project? All I have now its the Adobe CS5 Design Premium which has Adobe Professional Flash, I don't know if I can use that run your project.

    ReplyDelete
  12. Hey! It will be best if you get Flash Builder 4 or 4.5 to run the project.

    ReplyDelete
  13. Hi, Tony, your application is completely awesome, the only difference I see b/w yours and Safari is that each of your image is 100% flat, but Safari each image is curved. So if that can be improved, then it will be look more smooth. But still amazing after all.

    ReplyDelete
  14. This application is cool!! But is there a way to kill the screen-size border?

    ReplyDelete
  15. Thanks! It's always nice to read such comments!
    @Anonymous Im afraid I don't know if such curve of bitmap is even possible
    @Nan What do you mean by killing screen size border, cause I don't see such border

    ReplyDelete
  16. Hi, Tony, thank you for the reply, the application takes the full screen, and there is a light grey border line of the application. I am going to use this app for my website link page, but with a title on top you will see the border line. And I am also trying to figure out on how to set the app not full screen. I definitely see the param but it won't affect anything.
    Thank you again for the awesome app

    ReplyDelete
  17. Wow I've never noticed it, but actually when I switch to full screen I can see the border. Fortunately the fix is easy, you should set the border visibility style of the s:List to false like: borderVisible="false"

    Thanks Nan for noticing that!

    ReplyDelete
  18. Tony, thank you for your reply, actually all I want to get rid of its only the very outer border which is hardly noticed when the application is full screen. But I still wanna keep the border and space for each image, is there a way to do that?

    ReplyDelete
  19. That is exactly what borderVisible="false" on List does, it does not affect the images at all

    ReplyDelete