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;
}
}
}
This was very usefull to me! Thank you for writing that code.
Excellent code. Thanks for sharing! Very useful, very complete.
hey its an excellent code,
can I see it working somewhere
Hey All,
Please view the updated code:
http://manewc.com/2008/09/02/preloading-multiple-image-demo/
Sorry for any confusion!
Morgan
Very good!
Good job!
Thank very much !
I have an application that loads a bunch of thumbnails in the initial .swf file. Then when they click on the thumbnail, it displays the large version of that photo that it got from a url source. Now if I embed all the large images in my .swf, initial load could take forever for slow bandwidth users. So I want the images to load after website first loads. But the problem is, when they click, it sometimes takes 4-6 seconds for each photo to appear. How can I have the large images load in the background after initial page load? Will your image/array technique work for that?
If it does…
Lets say the user load the website, 10 seconds later the user clicks the first image to enlarge. By this time the array has been filled up with only the first two images (out of 10 total images). Will the user be able to quickly view that first image? Or will the user have to wait till the whole array is filled before they can view the first image in the array?
THANKS A TON FOR THE HELP!
If you want to see the specific example I am talking about, go to this address, then “photos”: http://www.fischerreinkewedding.com
Hi Brandon, I don’t feel like you are going to want to load all the large images after everything else. Ideally you will want to load the large image when the thumbnail image is clicked on. You should take a look at my image gallery project:
http://manewc.com/category/image-gallery-project/
more specifically probably this one:
http://manewc.com/2008/09/02/preloading-multiple-image-demo/
Thanks, and congratulations!
-Morgan