Previous Section Table of Contents Next Section

Hack 92 Dynamically Resize Content

figs/moderate.gif figs/hack92.gif

Ideally, your Flash content will display at the desired size even if the user resizes the browser window. Dynamically size your Flash content in response to the browser window to preserve the original design.

Although dynamically resizing the SWF to fit the browser window may seem simple, not many people seem to be able to make it work properly. So let's get hacking.

Although the Flash Player has the ability to resize the SWF to match the size of the browser window, you wouldn't want to do this for a number of reasons:

  • If you allow Flash content to resize too big, it can affect performance drastically, especially on a large screen.

  • Allowing Flash sites containing bitmaps to scale up can reveal the imperfections of the bitmaps.

  • Allowing Flash sites to resize too small can make them unusable from a user interface perspective.

  • Many parts of a typical Flash site are designed to be viewed at a particular size, and the graphical look and feel of the site can be compromised by viewing it at large sizes. For example, pixel fonts are designed to be viewed at a small size and start to look odd when viewed in a larger than intended SWF. Also, you may find that sans-serif and typewriter fonts may not scale proportionally.

A more desirable technique is to allow only parts of your site to be resized or to limit the degree to which they can be resized.

Although the designer may not want her site resizable out of concern for the look and feel, there are two problems. A site that looks cool on a big 21-inch screen may be unreadable on a 17-inch screen. Conversely, a Stage that fits on a 17-inch screen may appear quite small on a large screen, which has more, but smaller, pixels. A good compromise is to allow the site to scale 10% to 20% up or down. This keeps the site legible on a range of screen sizes without compromising the site design aesthetic.

Measuring the Stage

You can read the Stage dimensions very easily with the Stage class's static properties:

trace(Stage.width);

trace(Stage.height);

Although the trace( ) statements have no effect in the browser, you can see the results in Test Movie mode after resizing the Stage.

If the HTML scale attribute is set to anything other than the literal string "noScale", the Stage.width and Stage.height properties always return the internal Flash Stage dimensions (550 400 by default), although you can override this in ActionScript with:

Stage.scaleMode = "noScale";

You can also set the scale mode manually via the Scale drop-down list under FilePublish SettingsHTML. With the scaleMode set to "noScale", your Stage.width and Stage.height give the dimensions of the browser window.

The "noScale" mode tells Flash not to resize, but it allows you to control scaling through ActionScript. Note that if you set scaleMode to "showAll", "noBorder", or "exactFit", Stage.width and Stage.height return the Flash Stage size shown under ModifyDocument, regardless of the browser window size.

The next problem is that we don't want to be constantly checking the Stage or browser dimensions every frame, but only when they change (i.e., when the user resizes the browser). To do this, we read the dimensions within a listener event, as follows:

var stageListener = new Object( );

stageListener.onResize = function( ) {

  trace(Stage.height);

  trace(Stage.width);

};

Stage.scaleMode = "noScale";

Stage.addListener(stageListener);

Suppose we have two movie clips. The first is called scaleable_mc, which we want to act as a background and always fill the browser window. The second is called centered_mc, which we want to always stay centered and not scale.

In Figure 11-16, the light gray background gradient is our scaleable_mc clip, and the rectangle with the text "content" in the center represents our site content, centered_mc.

Figure 11-16. A background gradient with superimposed content
figs/flhk_1116.gif


Note that having our Flash content completely fill the Stage allows us to add all sorts of features that using a Flash site in front of an HTML tiled GIF background would not. We can easily add transparency effects (drop shadows or an irregularly shaped main site) without relying on Internet Explorer-only ActiveX controls, or we can add incidental animations or effects in the background. Using a vector gradient instead of a bitmap one also gives a smoother pattern. Although we are allowing a SWF with large dimensions, performance slows down only if you change large areas of the screen per frame. Our background area stays essentially constant, so the background does not affect performance.

The following code (available from this book's web site as varyStage.fla) will keep content_mc in its original position at its original scale, while scalable_mc will vary in size to fill the browser window:

function stageResize( ) {

  scalable_mc._width = Stage.width + 50;

  scalable_mc._height = Stage.height + 50;

}

Stage.scaleMode = "noScale";

myListener = new Object( );

myListener.onResize = function( ) {

  stageResize( );

};

Stage.addListener(myListener);

The last six lines are the ones that execute first (the other lines are a function definition), so let's consider those now. They set scaleMode to "noScale" and then set up a listener to respond to browser resize events.

The main work is done by the stageResize( ) function, which is invoked whenever the user resizes the browser window. The stageResize( ) function sets the background clip, scaleable_mc, to the same dimensions as the current browser window, in pixels, or rather the browser dimensions plus a bit more (+50) to also cover as much of the browser gutter as possible.

For the effect to work, select FilePublish SettingsHTML and set Dimensions to Percent and set the Scale to Default (Show All). To prevent the gutter around the browser window (and allow as much of our +50-pixel overlap to show up in the browser window, hand-edit the <body> tag in the HTML file to:

 <Body marginwidth="0" marginheight="0" topmargin="0" leftmargin="0">.

(Alternatively, you can set the body margins with CSS.)

Final Thoughts

A number of sites that emulate a "Flash operating system within the browser window" consist of a single, large background SWF that always covers the browser window overlain with smaller, nonscaling SWFs. This same technique can also be used successfully for traditional sites, substituting a GIF background tile pattern for a much more flexible and crisp vector background. Allowing a site to scale slightly aids readability immensely without cramping the style of the ubiquitous small (pixel font) text Flash site. There is no limit to adapting your interface to the browser window size. See http://www.it2004.jp/index2.html for an example of a complex interface that automatically reconfigures itself in response to browser window resizing. For a discussion of improving performance by buffering Stage.onResize events using an interval, see http://chattyfig.figleaf.com/ezmlm/ezmlm-cgi?1:msn:62851:dggpkifkacibblilcmok.

    Previous Section Table of Contents Next Section