There are some challenges in Flash that are addressed with such regularity that it can be surprising that no uniform way of accomplishing these tasks has emerged. One of these challenges is dynamic flash movie resizing through JavaScript. While websites have been doing this for years and the techniques involved are simple, there are enough moving parts involved to make it a chore to recode and deploy every time you launch a new site. BrowserCanvas bundles all of the code necessary to do Flash resizing into a single ActionScript file which is easy to deploy and reuse. It takes care of a lot of the maintenance work necessary to do Flash JavaScript resizing so that it can be deployed with minimal effort.

The best part of BrowserCanvas is that it requires no external JavaScript in the page to function. Deployment involves putting a single Actionscript class into your classpath and adding a couple lines of code to your project. That’s it. There is no messing around with JavaScript imports, there are no extensive Actionscript libraries. It is as clean and simple as possible.

Example Code

The following example shows you everything you need to do to randomly resize a flash movie every time the stage is clicked.

package {
   
   import flash.display.Sprite;
   import flash.events.MouseEvent;
   import com.dncompute.canvas.BrowserCanvas;

   public class DemoMain extends Sprite {

      private var canvas:BrowserCanvas;

      public function DemoMain() {
         canvas = new BrowserCanvas(stage);
         stage.addEventListener(MouseEvent.CLICK,randomSize);
      }

      public function randomSize(event:MouseEvent=null):void {
         canvas.width = String( Math.random()*500 + 200);
         canvas.height = String( Math.random()*500 + 200);
      }

   }

}

Live Examples

Below are links to different examples of BrowserCanvas in action. All of these examples are included in the browser canvas download file at the end of this post. You will note that none of these examples have additional javascript code embedded in them, all of the code is embedded in the Flash movie.

Caveats

While using BrowserCanvas is really simple, the code itself does have a little bit of complexity to it. Unfortunately, simple and cross-browser are rarely in the same sentence.

I’ve tested BrowserCanvas in a variety of modern browsers on both OSX and Windows. I have not tested BrowserCanvas in any of the golden oldies (IE 5.5 or less, Firefox 1.5 or less, Netscape anything, Safari 2.0 or less, Opera 8 or less) and don’t plan to add support for them.

The execution speed seems to be incredibly slow in Safari, and min/max behavior in Safari seems to only work in the SWF Object version of my demos. For most applications this shouldn’t be an issue, but I plan to investigate this further if I find the time.

I also have not tested BrowserCanvas in sites with complicated CSS layouts and AJAX interaction. If you have issues in any current browser, I’d be eager to hear about them. BrowserCanvas attempts to do a bunch of clever things in JavaScript, but I wouldn’t be surprised if some of these tricks don’t work in a few fringe cases. You can turn the browser specific hacks off, this is discussed in the comments for the BrowserCanvas class.

Also note that if you want to run the examples locally, you may need to make changes to the Flash Player security settings. You can find instructions on how to do this half way down this article from Adobe . You can access the Global Security Settings Panel by doing the following:
Right Click Any Flash Movie > Settings > Privacy (Tab) > Advanced (Button) > Global Security Settings Panel (Link)

History

Packaging up Flash based components for use across a large variety of websites is a regular challenge for professional Actionscript developers. With the release of Flash 9, Adobe has made this easier to accomplish with innovations such as SWC Actionscript libraries. SWC libraries work well when you are deploying components which are self contained, but don’t cover situations where a component requires external elements such as JavaScript libraries. Documenting and deploying all of the various pieces necessary for a component like this can be an onerous task. I’ve often longed for a way to package all of a component’s various pieces together into a single, easy to deploy package.

One way to do this is to insert the JavaScript directly from Flash, rather than embedding it in the HTML page. I spent some time when Flash 9 was first released looking into ways to accomplish this. My understanding at the time was that ExternalInterface only worked to call existing JavaScript functions on the page, so I focused my JavaScript code insertion efforts on the use of navigateToURL("javascript:XXX"). While this technique works to a limited degree, I abandoned my efforts because I found the results incredibly unwieldy to use with large codebases.

However, I recently discovered an article devoted to JavaScript injection by Peter McBride. Mr. McBride has dispelled many of my misconceptions surrounding ExternalInterface. He also demonstrates some clever techniques for embedding JavaScript into your Actionscript code. I highly recommend Mr. McBride’s article, it is a thorough and easy to follow introduction to the JavaScript injection techniques used in BrowserCanvas.

Update 26 Feb 2009:
I recently updated this class to v2 which should correct the IE issues which some users noted in the comments below. Internet Explorer does not properly handle min/max settings on object tags. To work around this, browser canvas was reparenting the object tag and swapping it’s id. Unfortunately, changing the ID of an object appears to break Flash’s External Interface calls. I’ve adjusted the class to account for this. If you are not setting min/max sizes, I would also recommend that you simply turn this hack off altogether when instantiating the class.

Update 07 Jul 2009:
There have been some issues coming up in the comments that I wanted to bubble up if those of you who may not read all the way down. First, the main reason BrowserCanvas fails for some people is due to issues with the id attribute of the embed/object tag. It’s important that the id attribute is set, otherwise the JavaScript code which resizes the flash movie has issues finding the element in the page. Other issues which people seem to face is failure while using the “static publishing method” of SWFObject. The “static publishing method”, while standards compliant, results in a double nested object tag which wreak havoc on the JavaScript resizing. Stick with the “dynamic publishing method” (the tutorial on the swfobject site gives step-by-step instructions for both methods).

Download Source