Fluid Flash Layouts

Photo Sharing and Video Hosting at PhotobucketHere’s how to do Fluid Flash layouts quickly without Flex.

Fluid layouts are not new but fhard to come by documentation.

To create a Flash fluid layout, essentially what you do is create a Flash movie that is set to 100% in HTML/SWFObject/XHTML but scaling set to noScale. Then in the flash script you position each element as needed on a resize handler.

This works great for applications built in Flash that will need to scale such as an IDE, a word processor, an image editing programs or programs that might have floating panels and tools.

1) Make your flash movie HTML scaled to the browser:

If you are using deconcept’s excellent SWFObject (be sure to download it) then see this sample for the HTML embedding with js swfobject.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>blipgames.com</title>

<script type="text/javascript" src="swfobject.js"></script>

<style type="text/css"> /* hide from ie on mac */

 html {

  height: 100%;

  overflow: hidden;

 }

#flashcontent {

  height: 100%;

 }

 /* end hide */

body {

  height: 100%;

  margin: 0;

  padding: 0;

}

</style>

</head>

<body>

 <div id="flashcontent">

  <strong>You need to upgrade your Flash Player</strong>

 </div>

<script type="text/javascript">

  // <![CDATA[

var so = new SWFObject("myMovie.swf", "myMovie", "100%", "100%", "8", "#efefef");

  so.addParam("scale", "noscale");

  so.write("flashcontent");

// ]]>

 </script>

</body>

</html>

2) Inside your flash code:

AS2

Stage.align = "TL"; // Top left align the stage

Stage.scaleMode = "noScale"; // Set noScale for containing stage.// CREATE A LISTENER OBJECTsizeListener = new Object();// ATTACH THE ON RESIZE EVENT TO THE LISTENERsizeListener.onResize = function()

{

// In the event call a method to move the items

// or, call each item here to be sized

movieToBeCentered._x = Stage.width/2;

movieToBeCentered._y = Stage.height/2;

movieToBeCentered._width = Stage.width * .5;

// add other movie clips to position...

};

// ADD THE LISTENER

Stage.addListener(sizeListener);

AS3

package

{

 import flash.display.*;

 import flash.events.*;

 import flash.utils.*;

public class AppMain extends MovieClip

 {

  public function AppMain()

  {

   stage.addEventListener(Event.RESIZE,onResize);

   stage.align = "TL"; // Top left align the stage

   stage.scaleMode = "noScale";  // items do not stretch to fit

  }
  public function onResize(event:Event)

  {

   // In the event call a method to move the items

   // or, call each item here to be sized

   movieToBeCentered.x = stage.width/2;

   movieToBeCentered.y = stage.height/2;

   movieToBeCentered.scaleX = stage.width * .5;

   // ... etc

  }

 }

}

This allows you to see easily how you can make a fluid layout in flash that scales with more of an alignment lock rather than the whole movie scaling.

A demo and toolkit will be available soon with an easy class library soon. For now you can go here to get a demo and source from the http://www.tutorio.com/tutorial/liquid-flash-layout site.

31 Responses to “Fluid Flash Layouts”

  1. Matt Says:

    Hi,

    I was very, very interested in your code because I’ve been having trouble getting stage resize events (none!) from a movie that is embedded with SWFObject.

    I realized when I looked at your code that I can not added the no scale param to the SO:

    so.addParam(”scale”, “noscale”);

    However, when I add this parameter (and when I used your whole unaltered page, something goes wrong, and I get the “you need to upgrade”, which is of course completely off base.

    Do you know what would cause your page to fail? Man I would really like to know

    thanks

    matt

  2. Matt Says:

    never mind, I was being a bonehead

    I had not, in the swf, changed its dimension to percents:

    [SWF(width=”100%”, height=”100%”)]

    and in the unaltered page, I had a different address to SWFObject:

  3. drawk Says:

    Hey Matt, Yeh the movie must be set to 100% height/width either in the SWFObject javascript or in AS3 script like you have it. I am preparing downloads for all my tutorials and just put this up here for some of the team members on a current project but thought I would share. I really need to get my blog running on drawlogic.com and downloadables for all my tutorials especially the AS3 ones that aren’t as avail on the internet as of yet. Please let me know if you solved your problem or if any more issues. SWFObject is a must have tool and it works great with fluid layouts. There is a few things I need to change in the as script above like the
    stage.align = “TL”; // Top left align the stage
    stage.scaleMode = “noScale”; // items do not stretch to fit

    I need to use the actual static class enumerations of
    Value Vertical Alignment Horizontal
    StageAlign.TOP Top Center
    StageAlign.BOTTOM Bottom Center
    StageAlign.LEFT Center Left
    StageAlign.RIGHT Center Right
    StageAlign.TOP_LEFT Top Left
    StageAlign.TOP_RIGHT Top Right
    StageAlign.BOTTOM_LEFT Bottom Left
    StageAlign.BOTTOM_RIGHT Bottom Right

    http://livedocs.adobe.com/flex/2/langref/flash/display/Stage.html#align
    AND for the scaleMode the pseudo enumerations (static classes with properties in AS3) of:
    scaleMode:String [read-write]
    A value from the StageScaleMode class that specifies which scale mode to use. The following are valid values:
    StageScaleMode.EXACT_FIT—The entire Flash application is visible in the specified area without distortion while maintaining the original aspect ratio of the application. Borders can appear on two sides of the application.
    StageScaleMode.SHOW_ALL—The entire Flash application is visible in the specified area without trying to preserve the original aspect ratio. Distortion can occur.
    StageScaleMode.NO_BORDER—The entire Flash application fills the specified area, without distortion but possibly with some cropping, while maintaining the original aspect ratio of the application.
    StageScaleMode.NO_SCALE—The entire Flash application is fixed, so that it remains unchanged even as the size of the player window changes. Cropping might occur if the player window is smaller than the content.
    http://livedocs.adobe.com/flex/2/langref/flash/display/Stage.html#scaleMode

  4. nuttshell Says:

    I am using FLash 8, AS 2.0.
    The code worked ONLY when i modified the example like this:

    Right before:
    sizeListener.onResize = function()
    {

    add some extra line:
    var sizeListener:Object=new Object();

    So it looks like this:

    ————————————-

    var sizeListener:Object=new Object();
    sizeListener.onResize = function()
    {

    ————————————-

  5. Daniel Says:

    I couldn’t understand some parts of this article o.us poetry, but I guess I just need to check some more resources regarding this, because it sounds interesting.

  6. Tamara Says:

    Hi – I’ve got everything to work great, but I have one small problem! 🙂

    I have an image as my scalable background and the problem is (because it’s people and not lines / solid color) it distors when I have it being the full stage.width and stage.height

    How do I specify that I want the entire image to grow in scale? And thus, if the browser is too long / wide for the image the background would just show up.

    Any ideas?

  7. drawk Says:

    You should set smoothing and only grow by the smallest width across. So when you should get the stage.stageWidth and stage.stageHeight. Once you have that whichever is smaller grab that. Then divide it by the same moviecliip.width or image.width. That will be your percentage that you can apply to the movieclip or image.width on both height and width so that it constrains the proportions. Essentially you are scaling up the image (it shoudl not scale beyond the actual file height widht if you want it to be crisp) by a percentage .height and .width. You figure out percentage by checking the actual movieclip width or height against the stage.stageHeight or stage.stageWidth.

  8. Tamara Says:

    Thanks for your help!! 🙂

  9. Wayne Says:

    Drawk,

    Did you ever finish the full tutorial for this and place it somewhere? Some of your posts state that you need to update some items and repost somewhere. Did that ever happen?

    Thanks,

    Wayne

  10. drawk Says:

    Hey Wayne, Yeh I did finish this will try to get it online this weekend. I like to make sure things are clean before I post.

  11. Wayne Says:

    Cool, I will be looking for it.
    I have 2 things left to do for the flash header and I believe this will take care of both of them.

    I am very hopeful it is a literal step by step not leaving any details to the presumed “you should already know these parts tutorials” as I am very much a beginner at AS3 right now, trying to get better.

    I am using Flash CS3 and AS3 in strict mode.
    I have to figure out how to adjust everything in the flash header based upon what the window size is.

    I also (which I believe is going to be the same thing) have to adjust the flash header based upon what the users resolution is. I think that if I change the flash header based upon the window size, it will not matter what the users resolution is.

    http://www.spectacularstuff.com/php-test/inprogress/home.php
    is what I am working on right now. I want it to resize when someone resizes the window and I want it at the correct size when someone first comes to the page for the first time.

    Wayne

  12. Wayne Says:

    I got past that last error however I get some really weird effects. I would probably have to show them to you. Is there a way I might be able to ask your help on a project of mine?

  13. drawk Says:

    Hey Wayne is it AS2 or AS3? If AS2 be sure to check this tutorial out and use it as a base: http://www.tutorio.com/tutorial/liquid-flash-layout

    If it is AS3 I am working on getting a better tutorial up on this soon. It is a popular topic and most of the AS3 kits are entire libraries but I want to show a simple, function that others can build on. I try to focus on getting right to the main code that drives things with my tutorials or howto’s so that people from all depths can implement it.

  14. Seth Says:

    Hey Drawk. Thanks for posting this. Big time help it is.

    I was reading your response to Tamara, and it sounds on the money for what I’m also trying to accomplish, except I’m not as skilled as translating your answer to AS2. Here’s where I got it to (which obviously isn’t working):

    filler._height = Stage.height / filler.height;

    “Filler” is the mc I want to scale in proportion, and both stage height and image height are the smaller lengths. Otherwise, I’ll keep checking back looking for your tutorial. 🙂

  15. drawk Says:

    Hey Seth,

    It depends on where your registration point is for that flash movieclip. Meaning the center point it is is upper left then you need to take into account the size of the filler in accordance to the middle of the stage. Unfortunately AS2 is classic to me so you might have to change slightly but the basic jist is this for any layout.

    If doing height…

    1. get stage height divide by two to get center
    2. get movieclip height
    3. adjust for registration point (if upper left you wil have to divide filler height by two).

    You are probably missing the last part. For instance if your registration point is upper left and you are working on height you would:

    filler._height = (Stage.height /2) – filler.height/2; (if upper left center register point)

    If you registration point is int the center this is not needed but registration points in the center (for your filler clip) are harder to work with in other ways on occasion so many times it is an adjustment to take into account the offset of the registration point compared to the center of the stage.

    If you filler movieclip is 200 height, let’s say stage is 800 height.

    filler._height = (Stage.height / 2) – (filler._height/2);
    woudl equate to
    filler._height = (800/2 = 400) – (200/2 = 100) = 300.

    So if your stage is 800, if your filler is 200, then you need to place it at 300 so that is it centered (since it is 200 height).

    I will try to clean this up more as typing this while doing some other stuff. But hopefully that set you on the right track.

    If your registration point was middle that last part would change.

    FOR HEIGHT ONLY

    TOP LEFT
    filler._height = (Stage.height / 2) – (filler._height/2);
    would equate to
    filler._height = (800/2 = 400) – (200/2 = 100) = 300.

    CENTERED
    filler._height = (Stage.height / 2);
    would equate to
    filler._height = (800/2 = 400) = 400 (since it is middle no change needed)

    BOTTOM LEFT WOULD BE TOP LEFT FLIPPED
    filler._height = (Stage.height / 2) – (filler._height/2);
    would equate to
    filler._height = (800/2 = 400) + (200/2 = 100) = 500.

    Hope that makes sense. For any layouts in Flash, PDF, DirectX, OpenGL etc it all goes back to getting viewable width, dividing by two, then adjusting for the size of the asset to be centered or fluid.

  16. Seth Says:

    Thanks so much Drawk. That’s incredibly cool that you took the time for such an in-depth reply to help a stranger out. Much appreciated and best wishes!

  17. Wayne Says:

    Drawk,

    It is AS3. There is not much out there at this time. I was able to find the following websites that can help out.
    http://abeall.com/files/flash/tests/ActionScript3/Layout.as
    http://abeall.com/files/flash/tests/ActionScript3/layout.fla

    I think I can modify those for what I require but that doesn’t explain to me how to do it or why it is working.

    Nor does it explain to my why the layout.fla works without the Layout.as file linked to it.

    Wayne

  18. drawk Says:

    Wayne, it is either the document class or you can included it and then make a new Layout object. That looks alot like senocular’s layout classes. If you look in the resize() method you can see what I was talking about.

    if(elem.center)
    xt = w/2 – bounds.width/2;
    if(elem.middle)
    yt = h/2 – bounds.height/2;

  19. abeall Says:

    A few quick comments about that abeall layout class (yes, ’tis mine):

    1) It is not “linked” because in the Flash IDE (where .flas live) you don’t actually have to declare any imports if the class is in the the classpath. Same with all intrinsic classes, you’ll notice. You only have to declare imports in .as files. Maybe not the best practice to not declare your imports (then again, timeline AS is not the best practice), but in the Flash IDE it lets you get away with it, and I’m a scripthackorz, yo. 😉

    2) My Layout class was indeed sort of the precursor to senocular’s:
    http://www.actionscript.org/forums/showthread.php3?t=142694
    Senocular’s is far more advanced. The only possible advantage to mine is that it’s largely automatic, you just put your movie clips around the stage and it will automatically calculate the margins for you based on where you put them at design time and your desired anchors(left/right/top.etc). For a simple minded designer like me, that can be nice. If, however, you are instantiating all your clips through AS anyway, look into senocular’s, it has some great features.

    3) I added a few basic comments to the files.

    Cheers.

  20. Bougie Says:

    I thought it would be a good idea to post a link to my Flash Layout Engine http://blog.bouguerra.org/?page_id=13

  21. drawk Says:

    Thanks Bougie, it looks very interesting. There is also a senocular layout engine and what I was trying to do here is get to the core of what enabled fluid layouts, and that is the stage and onResize events. I hope there are many more layout engines and more knowledge gained in making full use of the screen real estate.

  22. bougie Says:

    Hey Drawk; I searched for senocular layout engine and couldn’t find anything… I don’t really think there is any good AS layout engine out there and that’s the reason why I built mine. It is very similar to Microsoft’s WPF when it comes to architecture and margins feature but it comes with added features. For example, instead of using left, right, top, bottom or center as alignments, I use a number between 0 and 1.
    0 corresponds to left or top and 1 corresponds to right or bottom and everything else falls in between…
    In the link below, you can see a demo where I have a vertical stackPanel that has 3 children – 2 horizontal stackPanels and one UIElement( square ). Each of the 2 horizontal stackPanels have 3 UIElement children. To test it, you can click on any UIElement ( square ) or stackPanel’s border and animate it by clicking on the animate button and you will see the power of the engine.
    http://blog.bouguerra.org/flash/layout/TestEverything.html

  23. drawk Says:

    Hey bougie,

    Here is the senocular one; http://www.senocular.com/flash/actionscript.php?file=ActionScript_3.0/com/senocular/display/Layout.as

    But I think that making it easy for WPF layout to cross into flex/flash is awesome. There is also Degrafa that might be trying some of this. I think this is all good along with yours.

  24. bougie Says:

    Thanks drawk! I think Senocular’s is more like a tool than an engine. Cheers!

  25. foreground Says:

    Га-Га ) ) )

  26. Wong Says:

    simple and easy to understand, thanks man !

  27. daniel bryan as a kid Says:

    Hi to every body, it’s my first pay a visit of this
    website; this webpage consists of amazing and in fact excellent data designed for visitors.

  28. Teri Says:

    Digital Audio Workstations have taken center-stage in the music business, and
    because there are variances involved when syncing
    laptops with desktops for interactive DJ triggering, it can be very important to have a router that can handle vast
    amounts of information in a given moment. You can certainly get
    exactly what you want, but you might also find the
    huge variety of options confusing. 4GHz and 5GHz bands, the EA4500
    router is very reliable reaching farthest corner of your large house, eliminating the requirement of adding a wireless range extender.


Leave a comment