Tutorial details:
Written by:
Jason M. Batchelor
Time:
25 minutes
Difficulty Level:
Intermediate
Requirements:
Flash 5 and above
Topics Covered:
Defeating Flash's auto-scaling of objects.
Assumed knowledge:
Variables, Paths, MovieClips, Javascript.
Download the FLA
See an Example

A little background:

I'd created this Flash application that my boss wanted to fill the screen, no matter what size the browser window has been resized to. The code which I adapted to dynamically resize the Flash app, however, ended up serving a second purpose. My boss liked everything about the resize, except for the way it distorted the app's Flash-based form, which was a movie clip loaded into the master movie via LoadMovie.

If you set the SCALE parameter in the hosting HTML for the Flash movie as "exactfit", Flash automatically scales everything to fit the dimensions that you've chosen for the width and height attributes. If your width and height parameters are proportionally correct, this shouldn't screw things up too badly, except that text doesn't always scale gracefully, and can end up (as was the case with my application) making the text antialias or "fuzz up." I found a way to counter this automatic scaling of a movieclip. You might use this to keep specific 'clips at a set size, no matter what size you make the hosting movie... for example, a "window" clip which you want to stay at it's originally-designed size.

You need to pass the dimensions of the hosting page to the inside of the movie. (Flash MX allows you to find the dimensions of a movie, internally, and it has an onResize handler on the Stage object, but I haven't gotten onResize to work, yet, so this information is mainly for users of Flash 5. However, I have tested this method on the Flash 6 plugin, however, and it works fine in that environment as well). The key is in compairing the dimensions of the surrounding page with the original size of the movie.

Place something like the following into the body of your page:

function writeFlash() {
        // Jason M. Batchelor
        // mori57@mac.com
        // Determine what client we're using...
        NS4=(document.layers);
       
        // The only reason we have to do this based on client-type, is
        because IE does not
        // support the use of the onResize event when there is an ActiveX
        control on a page.
        // If you want IE to automatically reload on a resize, you'll have
        to set up a
        // frameset like the one that this is contained within.
        if (NS4) onresize = location.reload();
       
        // If it's Netscape, use innerWidth, if IE,
        document.body.clientWidth, to ascertain
        // the amount of screen space you have available.Do the same to
        retrieve the height
        // of the page.
        var winWid = (NS4) ? innerWidth : document.body.clientWidth;
        // -25 takes into account scrollbars. Take this out if you don't
        have to worry about
        // scrollbars on your page.
        winWid = winWid - 25;
        var winHgt = (NS4) ? innerHeight : document.body.clientHeight;
        winHgt = winHgt;
       
        // Create a string that contains the <OBJECT> and
        <EMBED> code for your Flash movie.
        // I've omitted the CODEBASE and PLUGINPAGE attributes, as you can
        get the latest attributes
        // when you first generate your <object> and <embed>
        code from within Flash.
        var imStr = "<OBJECT
        classid='clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'"

        + " WIDTH='" + winWid + "' HEIGHT='" + winHgt +
        "' align='left'>"
        + " <PARAM NAME=movie VALUE='resizex.swf?scaleX=" +
        winWid + "&scaleY=" + winHgt + "'>"
        + " <PARAM NAME=quality VALUE=high>"
        + " <PARAM NAME=bgcolor VALUE=#FFFFFF>"
        + " <param name='SCALE' value='exactfit'>"
        + " <EMBED src='resizex.swf?scaleX=" + winWid +
        "&scaleY=" + winHgt + "'"
        + " quality=high bgcolor=#FFFFFF WIDTH='" + winWid +
        "'"
        + " HEIGHT='" + winHgt + "'
        TYPE='application/x-shockwave-flash'"

        + " align='left' scale='exactfit'>"
        + " </EMBED> "
        + " </OBJECT>";
       
        // Now, with all the above plugged in, tell Javascript to write out
        the plugin code.
        document.write(imStr);
}
writeFlash(); // Call the routine, above.

Now in the onClipEvent(load) of the movieclip you want to counter-scale:

onClipEvent(load){
        var winWid = _root.scaleX;
        var winHgt = _root.scaleY;
        var origWid = this._width; // These are only included to show the difference,
        var origHgt = this._height; // and should not be needed in most cases.
        with(this){
                _xscale = winWid != 100 ? Math.round((_root._width/winWid) * 100) : 100;
                _yscale = winHgt != 100 ? Math.round((_root._height/winHgt) * 100) : 100;
        }
}

There are a number of other uses for this technique, and if you combine this with the use of pop-up Javascript windows, you can fine-tune the way the page is displayed for your users, without unnecessarily sacrificing the clarity of your original design.