How to Position Movie Clips Based on Browser Resizing

ActionScript 2.0 Flash

It’s not hard to make a SWF resize itself to the dimensions of the browser.  All it takes, in fact, is to set the width and height attributes of the HTML’s <object> <param> element and/or <embed> element to 100%.  There are a number of ways to determine the SWF’s display, too:  show all (default) makes the entire movie visible while maintaining the original aspect ratio of the SWF (if the browser’s aspect ratio differs, you’ll get the equivalent of “letterbox” borders either horizontally or vertically); no border gets rid those potential borders, but may crop parts of the SWF instead; exact fit distorts the SWF, if necessary, to make the entire movie visible without borders or cropping.  See Adobe TechNote 12701 for complete details.

Fine and good.  Now, what if you want to allow the Stage to resize, but not its contents?  What if you want to adjust the position of various movie clips — such as a logo, navigation, or content area — in response to the Stage’s new dimensions as the browser is resized?  Luckily, that’s not hard either.  :)   Let’s take a look. 

An answer, short and sweet

Open a new FLA and draw a quick shape — a circle will do.  Convert the shape to a movie clip (Modify > Convert to Symbol…, then choose Movie Clip) and give the clip an instance name via the Property inspector.  For this example, let’s call it mcLogo.

Create a scripts layer and type the following into frame 1:

Stage.scaleMode = "noScale";
Stage.align = "TL";
var stageListener:Object = new Object ();
stageListener.onResize = positionContent;

function positionContent():Void {
   mcLogo._x = Stage.width - mcLogo._width;
   mcLogo._y = Stage.height - mcLogo._height;

Test your SWF, and you’ll see the circle hug the lower right corner as you resize the SWF’s dimensions in Flash.  Either that, or publish to an HTML file and set the width and height attributes for both the <option> <param> element and the <embed> element to 100% and resize the browser.

How it works

In the first line, we’re telling the SWF not to scale itself.  In your HTML — this is important — you’re going to set the width and height to 100%, but the SWF itself will not scale to fit those dimensions.  In the second line, we’re telling the SWF to register itself to its upper left (top left) corner.

Next, an arbitrarily named variable, stageListener, is declared as a generic Object instance.  This object acts as an “ambassador” for the Stage.onResize event, so we need to assign a function to a new onResize property of our object, rather than of Stage directly.  In this example, the function is arbitrarily named positionContent() and is defined shortly below.  Note:  if you like, you may assign a function literal …

stageListener.onResize = function() {
  // instructions here

… but in this case, I chose a named function because you may want position dozens of movie clips, and it’s arguably “cleaner code” to define the function separately.  If you go the named function route, as we’re doing, make sure to omit the parentheses in this line, as shown.

The next line adds our ambassador as a listener to the Stage.  The Stage.addEventListner() method is what “wires up” the listener object to the object that dispatches the event (here, the Stage).

Finally, the custom positionContent() function tells mcLogo what to do.  In this case the movie clip’s _x property is set to the width of the Stage minus its own width.  That makes it hug the right side.  To center this clip, you could set its MovieClip._x property to half the Stage’s width minus half its own …

mcLogo._x = Stage.width / 2 - mcLogo._width / 2;

Follow suit for vertical positioning.  Makes sense, right?  Be sure to call the positionContent() function after you declare it, to make sure everything is positioned at the start, otherwise the Stage/browser would have to resize first.

By the way, this setup expects movie clips to be registered to their upper left corners.  If mcLogo’s shape was centered horizontally in its own timeline, you would only have to minus half its width from the Stage’s width to make it hug the right hand side.  If you want a 20 pixel buffer between this right-aligned clip and the Stage, account for that extra 20:

mcLogo._x = Stage.width - mcLogo._width - 20;

To keep a clip to the left side, set its _x to 0.

Keep in mind, you’re not limited to setting MovieClip._x and _y properties.  You may adjust a clip’s _width, _height, _xscale, _yscale … whatever you like.  Experiment and have fun with it!  For every clip you wish to position, simply add its entry to the positionContent() function.  Note, below, that an mcNav clip is being set to a position based on the original mcLogo clip.  Here, both clips would hug the right edge of the Stage, and mcNav would float below mcLogo, with a buffer of 20 pixels.

function positionContent():Void {
  mcLogo._x = Stage.width - mcLogo._width;
  mcLogo._y = 20;
  mcNav._x = Stage.width - mcNav._width;
  mcNav._y = mcLogo._y + mcLogo._height + 20;

Note:  See How to Fix Wrong-sized SWFs in Firefox to work around a common issue with 100%-sized SWFs in Firefox.  (Thanks for the cross-reference suggestion, Markus!)

Leave a Reply