Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Quick Tip: How to Automatically Resize an Image to Fit the Screen

by
Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

This Quick Tip explains how to use an image as a website background and scale it proportionally to the stage size. It's great for when you're using a SWF that's full-height and full-width inside a webpage.

iMac icon by bobbyperux.


Final Result Preview

Take a look at what we'll be working on. Resize your browser window and click the SWF to auto-resize the image.


Step 1: Create a New File

Let's start by creating a new Actionscript 3.0 File. Save it as resize.fla wherever you want - I'll assume C:\resize\resize.fla


Step 2: Configure the Folders

Let's create the folders we need for this tutorial. If you are familiar with classpaths and you have your own classpath, create the folder \org\display\ inside it (assuming you don't already have one with the same name).

Otherwise, create the folder \org\display in the same folder as the resize.fla document (for example: C:\resize\org\display).


Step 3: Import an Image File

Import an image to your FLA's library so that we can use it to test the effect. Click File > Import > "Import to library".

In the dialog that opens, find the file you'd like to use. The sky image I picked is available in the Source download at the top of the page.


Step 4: Configure the Image for Export

Next we'll export our image for ActionScript, so that we can refer to it in our code.

First open your library (if you can't see it, click Window > Library), right-click the image, and click Properties.

Change its name to "Sky."

If the advanced options are not visible, click Advanced in the bottom-right corner of the Properties window. Check the options, "Export for ActionScript" and "Export in Frame 1", using the name Sky for the class and flash.display.BitmapData for the base class. Also make sure the option "Allow smoothing" is checked; this option will ensure that we maintain good image quality when resizing the image.

Click OK to close the Properties panel. So, now we have configured everything in our FLA, you can save it.


Step 5: Custom Class OffsetResize

Now let's create a new ActionScript document and save it inside our \org\display\ folder as OffsetResize.as (for example: C:\resize\org\display\OffsetResize.as), or inside the \org\display\ folder in your classpath.

Next: code. Check out the comments.

package org.display{
	
    //Import the needed classes for this object
	import flash.display.Sprite;
	import flash.display.DisplayObject;
	import flash.events.Event;
	

    //Creating a new class extending the Sprite class
	public class OffsetResize extends Sprite{
		
        //Create the static constants for maximum and minimum
        //We will use this for the offsetType property
		public static const MAX:String="max";
		public static const MIN:String="min";

        //The kind of the resize -- whether the image is bigger or smaller than the stage
		private var _offsetType:String;
		
        //The constructor function
		public function OffsetResize($child:DisplayObject,$offsetType:String="max"):void{

        	//The offsetType; if no value is set the "max" value will be automatically assumed
			_offsetType=$offsetType;

            //Add the child here, any kind of DisplayObject
			addChild($child);

            //Check if this object is on stage. if so, call the init() function
			if(stage) init();

            //If it's not on stage it will listen for when it's added to the stage and then call the init() function
			else addEventListener(Event.ADDED_TO_STAGE,init);

            //This will check when this object is removed from the stage and call the end() function
			addEventListener(Event.REMOVED_FROM_STAGE,end);
		}
		

        //The init() function (called when the object is in the stage)
        //The Event=null parameter is because we used the init() without any parameter in the constructor
		// and because it's also used as an event listener (ADDED_TO_STAGE)
		private function init(e:Event=null):void{

        	//Detect when the stage is resized and call the stageResize() function
			stage.addEventListener(Event.RESIZE,stageResize);

            //Call the stageResize() function now, too
			stageResize();
		}
		
        //The stageResize() function will be called every time the stage is resized
        //The e:Event=null parameter is because we have called the stageResize() function without a parameter
		private function stageResize(e:Event=null):void{

        	//Calculate the width ratio by dividing the stage's width by the object's width
			var px:Number=stage.stageWidth/width;

            //Calculate the height ratio by dividing the stage's height by the object's height
			var py:Number=stage.stageHeight/height;

            /*
            	This is the ternary operator; in one line it checks if _offsetType is "max".
                If so, it sets the variable div as the maximum value between the width's ratio and the height's ratio.
                If not, it sets the variable div as the minimum value between the width's ratio and the height's ratio.
                So, this line is responsible for whether the image is bigger or smaller than the stage.
            */
			var div:Number=_offsetType=="max" ? Math.max(px,py) : Math.min(px,py);

            //These two lines resize this object according to the division ratio.
            //If we use scaleX or scaleY here it wont work as we need it to.
			width*=div;
			height*=div;

            //These two lines are responsible for centering this object on the stage.
			x=(stage.stageWidth/2)-(width/2);
			y=(stage.stageHeight/2)-(height/2);
		}
		
        //This function is called when this object is removed from stage, as we don't need the stageResize() function any more
		private function end(e:Event):void{
        	//Remove the RESIZE listener from the stage
			stage.removeEventListener(Event.RESIZE,stageResize);
		}
		
        /*
        	Here we create the offsetType parameter, so we can change how the object
            resizes dynamically
        */
		public function set offsetType(type:String):void{
			_offsetType=type;

            //After changing the type we call stageResize function again to update
			if(stage) stageResize();
		}
		
        //Just for if we want to know what the offsetType is
		public function get offsetType():String{ return _offsetType; }
	}
}

Now you can save the OffsetResize.as file. You can close it if you want; from now on, we won't be editing it any more, just using it inside other classes.


Step 6: Configure the Document Class

Now switch back to the FLA and let's assign a document class to it. (Not familiar with document classes? Read this quick introduction.)

Open the Properties panel of the FLA by clicking in any blank space on the stage (with no objects selected), then clicking Window > Properties.

In the panel that opens, type "Main" for the Class (or Document Class, in Flash CS3).

Save the FLA again but do not close it.


Step 7: Code the Document Class

We could write our code directly in the timeline, but that's not a good habit; the purpose of the document class is to eliminate timeline programming.

So, create a new ActionScript File and save it as "Main.as" in the same folder as your FLA (for example: C:\resize\Main.as).

Let's code it now (see the comments in the code):

package{
	
    //Let's import the needed classes
	import org.display.OffsetResize;
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
    //We are extending the Sprite class, rather than MovieClip, since we won't use any timeline animation here
	public class Main extends Sprite{
		
        //This will be the instance of our custom object OffsetResize
		private var _bg:OffsetResize;
		
        //The constructor
		public function Main():void{

        	/*
            	We could use the stage property directly here, but I'm assuming that a lot of people
                create a document like "base.swf" which loads the "main.swf" file -- in which case our
                main.swf wouldn't have the stage property.
				
                But it checks if there is a stage property. We can use this swf we will create with
                or without the base.swf; in this case we will use it without the base.swf, but it's
                prepared to use with the latter if we want.

                So this line will check if our swf is on the stage, and, if so, call init().
            */
			if(stage) init();

            //If not on the stage it will call the init() function only when it's added to the stage
			else addEventListener(Event.ADDED_TO_STAGE,init);
		}
		
        //The init function is called only when the object is in the stage
        //It was explained before whe we are using this in the constructor function
		private function init(e:Event=null):void{

        	//Setting how the stage will scale (it will not scale) and its alignment (top-left corner)
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align=StageAlign.TOP_LEFT;

            //Remember the picture in the library? Well, this is why we exported it for AS.
            //Let's create a Bitmap object with that image:
			var picture:Bitmap=new Bitmap(new Sky(0,0));

            //Now we create an instance of the OffsetResize class we coded before.
            //The second parameter is optional and can be left blank; its value can be OffsetResize.MAX or OffsetResize.MIN.
			_bg=new OffsetResize(picture,OffsetResize.MIN);

            //add the instance of the OffsetResize to the stage at child index 0, so it will be behind everything (it's a background)
			stage.addChildAt(_bg,0);

            //The code so far is enough to make this work, but I will show how to change the offsetType dynamically.
            //So let's add a MOUSE_DOWN event, which will call the mouseDown() function when we click on the stage.
			stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
		}
		
        //This function is called every time that we click the stage
		private function mouseDown(e:MouseEvent):void{
        	/*
            	This is the ternary operator, it's a compact version of this long if statement:
                if(_bg.offsetType==OffsetResize.MAX){
                	_bg.offsetType=OffsetResize.MIN;
                }
                else{
                	_bg.offsetType=OffsetResize.MAX;
                }
            */
			_bg.offsetType = _bg.offsetType==OffsetResize.MAX ? OffsetResize.MIN : OffsetResize.MAX;
		}
	}
}

Step 8: Test It Out

Check if it's alright.

  • We need to have an image in the Library called "Sky" which is exported for ActionScript with a class name of Sky and a base class of flash.display.BitmapData.
  • We must also have the document class set to "Main"
  • the Main.as file in the same folder as the FLA
  • and the OffsetResize.as file inside \org\display (which is either inside the same folder as the .fla file or is inside the classpath).

If all these requirements are met, you can test it now!

Conclusion

We created a custom class called "OffsetResize", which resizes a specified object according to the stage's size. If you created it in your classpath then you can use it wherever you want: all you need to do is import the OffsetResize object and use it; it's extendable and reusable. But remember it's to use with scalable content, for example a SWF in HTML which takes up 100% of the width and height.

Thanks for reading! Post any questions in the comments.

Advertisement