16May

Preloading Multiple Images with Actionscript

6 comments so far

Please view my updated code

One of my new projects involves a lot of imagery so I decided to write a class that I could send it an array of images and preload them with a loading bar. The code below doesn’t have a loading bar, but if you trace out the code you can see how you can integrate a loading animation to the code. Here is what I have that works for what I need, although I would like to go through it to see if I can make it more efficient.

Here is the Main Document Class:

package {
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.text.TextFormat;
	import flash.text.TextField;
	import fl.controls.TextArea;
	import fl.controls.ScrollPolicy;

	public class Main extends Sprite
	{
		// array of all images to be prelaoded before the movie begins:
		private var imgArray:Array;

		// the class to handle all the images
		private var imgPreload:MultipleImagePreload;

		//text area component
		private var output:TextArea;  

		public function Main()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;

			showOutput();

			init();
		}

		private function init():void
		{

			imgArray = new Array();
			imgArray[0] = "http://manewc.com/projects/flash/i/infused-blackraspberry.png";
			imgArray[1] = "http://manewc.com/projects/flash/i/infused-blueberry.png";
			imgArray[2] = "http://manewc.com/projects/flash/i/infused-coconut.png";
			imgArray[3] = "http://manewc.com/projects/flash/i/infused-lemonlime.png";
			imgArray[4] = "http://manewc.com/projects/flash/i/infused-peach.png";
			imgArray[5] = "http://manewc.com/projects/flash/i/infused-pineappleorange.png";
			imgArray[6] = "http://manewc.com/projects/flash/i/infused-strawberry.png";

			imgPreload = new MultipleImagePreload(imgArray);
			addChild ( imgPreload );

			stage.addEventListener ( Event.ENTER_FRAME, checkPreload );

		}

		private function checkPreload(e:Event):void
		{
			if ( imgPreload.chkLoaded )
			{
				Message ( "\n====================\nALL IMAGES LOADED\n====================\n" );

				stage.removeEventListener ( Event.ENTER_FRAME, checkPreload );
			}
		}

		private function showOutput():void
        {
			output = new TextArea();
			output.verticalScrollPolicy = ScrollPolicy.ON;
			output.condenseWhite = true;
			output.setSize(stage.stageWidth, stage.stageHeight);
			output.move(0, 0);
			addChild(output);
        }

		public function Message(msg:String):void
		{
			output.appendText ( msg );
		}

	}
}

The class that is the Preloader

package
{
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.setInterval;
	import flash.utils.clearInterval;

	public class MultipleImagePreload extends Sprite
	{
		public var images:Array;
		public var chkLoaded:Boolean = false;

		private var imgArray:Array;

		// array of images.. onload event
		private var imgLoadArray:Array;

		// array of LoadImage class
		private var loadArray:Array;

		// variables for our timer events
		private var initLoadTimer:uint;
		private var preLoadTimer:uint;

		// variables for the preload process
		private var getTotalBits:Number; // the tally for the total bits
		private var imageTotalSize:Number;
		private var imagePreLoadSize:Number; // the tally for preloading

		public function MultipleImagePreload(images:Array)
		{
			imgArray = images;

			// Load in the images.
			loadArray = new Array();

			for ( var i:uint; i < images.length; i++ )
			{
				// load the image
				loadArray[i] = new LoadImage( imgArray[i] );

				// display the image to stage
				addChild ( loadArray[i] );

				// send them off the stage
				loadArray[i].x = -9999;
			}

			initLoadTimer = setInterval(onLoadImage, 500);
		}

		private function onLoadImage():void
		{
			var imgLoadArray = new Array();

			for ( var i:uint=0; i < imgArray.length; i++ )
			{
				getTotalBits = loadArray[i].getBits();

				if ( getTotalBits > 0 )
				{
					// check again.
					imgLoadArray[i] = loadArray[i];
				}
			}

			if ( imgLoadArray.length == imgArray.length )
			{

				clearInterval ( initLoadTimer );

				imageTotalSize = 0;

				// add up the size of all images
				for ( var u:uint=0; u < imgArray.length; u++ )
				{
					if ( loadArray[u].getBits() ) /* Safari is requiring this */
					{
						imageTotalSize += loadArray[u].getBits();

					}
				}

				Main(root).Message( "Total Size (bits): " + imageTotalSize + "\n" );

				// we now have recorded all file sizes.. now start the preloading
				preLoadTimer = setInterval(preLoadImage, 50);
			}
		}

		private var loadStat:Number;

		private function preLoadImage():void
		{
			imagePreLoadSize = 0;

			// add up the size of all images
			for ( var p:uint=0; p < imgArray.length; p++ )
			{
				imagePreLoadSize += loadArray[p].getBitsLoaded();
			}

			if ( ( imagePreLoadSize / imageTotalSize ) )
			{
				loadStat = Math.floor(100 * (imagePreLoadSize / imageTotalSize));

				if ( loadStat >= 100 )
				{
					// clear the timer
					clearInterval ( preLoadTimer );

					// set the boolean variable to true to notify all images are loaded
					chkLoaded = true;

					Main(root).Message ("100% Loaded\n");
				}
				else
				{
					Main(root).Message (Math.floor(100 * (imagePreLoadSize / imageTotalSize)) + "% Loaded\n");
				}
			}
		}
	}
}

The class that will load in the image

package {
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.net.URLRequest;

    public class LoadImage extends Sprite {

		private var url:String;
		private var imageHolder:Sprite;
		public var bits:Number;
		public var bitsLoaded:Number;
		public var totalBits:Number;

        public function LoadImage(url:String) {
			var loader:Loader = new Loader();
            configureListeners(loader.contentLoaderInfo);

            var request:URLRequest = new URLRequest( url );
            loader.load(request);

			imageHolder = new Sprite();
			addChild ( imageHolder );
            imageHolder.addChild(loader);
        }

        private function configureListeners(dispatcher:IEventDispatcher):void {
			dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			dispatcher.addEventListener(Event.COMPLETE, completeHandler);
        }

        private function completeHandler(event:Event):void {
			Main(root).Message( "Image Load Event Complete\n" )
		}

		public function getBits()
		{
			return ( bits );
		}

		public function getBitsLoaded()
		{
			return ( bitsLoaded );
		}

        private function progressHandler(event:ProgressEvent):void {
			bitsLoaded = event.bytesLoaded;
			bits = event.bytesTotal;
        }

    }
}

Share/Save/Bookmark

Friday, May 16th, 2008 at 8:37 am and is filed under Image Effects, Preloading, manewc.com. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

6 Responses to “Preloading Multiple Images with Actionscript”

  1. Posted by Lubakis 3rd August, 2008 at 12:23 pm

    This was very usefull to me! Thank you for writing that code.

  2. Posted by Erik 11th August, 2008 at 9:17 am

    Excellent code. Thanks for sharing! Very useful, very complete.

  3. Posted by awais 1st September, 2008 at 2:11 am

    hey its an excellent code,
    can I see it working somewhere

  4. Posted by Preloading Multiple Image - Demo | actionscript 3 | morgan newcomb, website and flash developer, burlington, vermont 2nd September, 2008 at 9:38 am

    [...] http://manewc.com/2008/05/16/preloading-multiple-images-with-actionscript/ [...]

  5. Posted by admin 2nd September, 2008 at 9:45 am

    Hey All,

    Please view the updated code:

    http://manewc.com/2008/09/02/preloading-multiple-image-demo/

    Sorry for any confusion!

    Morgan

  6. Posted by Bruno Mikoski 2nd September, 2008 at 9:45 am

    Very good!

    Good job!

Leave a reply