Loading and scaling external Shockwaves to stage size in AS3

I’m just finished with an affiliate system currently in use by Videoslots.com but more sites might be connected in the future. It’s made with Clojure’s Ring and Compojure and uses MongoDB for its database. To the right you see the result of this article, one of my affiliate banners, read on below to get the skinny on how it works.

It also needs to handle Shockwave banners. It goes like this:

1.) The merchant uploads a shockwave banner to the affiliate system. The requirements for this banner is that it must not have any click functionality in it (as to why we’ll get to that soon enough). It’s basically just a glorified animated gif.

2.) An affiliate can now in his own affiliate admin section create campaigns with the help of the banners the merchant uploaded. Each campaign will have its own load url which will be automatically created by the system, so the affiliate can track how many times the banner is loaded. The affiliate chooses the landing page but the system will create its own click url so we can track how many times the banner was clicked. In short, the affiliate system is both serving the banners and redirecting people to the landing pages and collecting metrics for everything.

Doing this with static images is no problem as an image can easily be the content of an anchor tag. But what about shockwaves, having a shockwave object as the contents of an anchor tag can be problematic…

The solution is to create a flash loader that in turn will load the banner the merchant uploaded, with the help of the automatically created load url of course. This loader needs to resize the loaded banner according to the size of the loaded banner and it should be able to do this regardless of the dimension and/or aspect ratios of the loaded banner.

The AS3 code in the loader:

var paramList:Object = this.root.loaderInfo.parameters;

var bkg     = new Loader();
var urlReq     = new URLRequest(paramList['loadtarget']);
var banner = this.addChildAt(bkg, 0);
bkg.contentLoaderInfo.addEventListener(Event.COMPLETE, this.onLoadComplete);

Mouse.cursor = "button";

this.root.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent){

function onLoadComplete(event:Event){
	var cWidth = int(paramList['width']);
	var cHeight = int(paramList['height']);
	var sy = 1000 / cHeight;
	var sx = 1000 / cWidth;
	var sWith = sx >= sy ? sx : sy;
	var ty, tx;
	if(cHeight > cWidth){
		tx = 0;
		ty = ((cHeight - cWidth) / 2) * sWith;
	}else if(cWidth > cHeight){
		ty = 0;
		tx = ((cWidth - cHeight) / 2) * sWith;
		ty = 0;
		tx = 0;
		scaleX = sWith; 
		scaleY = sWith; 
		x         = -tx; 
		y         = -ty;

First we load all the parameters with the help of the global root.loaderInfo.parameters. As you can see it needs to contain loadtarget (the url of the banner to load), clickUrl, width and height.

Next we check if we’re dealing with a tower or a “normal” horizontal banner, we scale X and Y accordingly. The problem is that the quadratic 1000×1000 loader swf will scale down to the minimum size. If we for example load a 160×600 banner the loader will scale from a square with a 1000 pixel side down to a square with a 160 pixel side situated in the middle vertically, ie at y: 220. We then scale the banner 6.25 times in both dimensions and transfer it 220 pixels up.

Note the Mouse.cursor = “button”; call, a nifty way to simply show the pointing hand no matter what as soon as the mouse cursor rolls over the banner.

Here is how the html could look like:

<object width="250" height="625">
	<param name="movie" value="loader.swf"></param>
	<param name="allowFullScreen" value="false"></param>
	<param name="scale" value="default"></param>
	<param name="wmode" value="window"></param>
	<param name="FlashVars" value="clickUrl=http://www.google.com&loadtarget=tower.swf&width=250&height=625"></param>
	<embed src="loader.swf" FlashVars="clickUrl=http://www.google.com&loadtarget=tower.swf&width=250&height=625" type="application/x-shockwave-flash" width="250" height="625">

Note the numerous places we need to include width and height in to make it work in as many browsers as possible.

Related Posts

Tags: , , , ,