LoaderCollection:
Loading multiple files with a single progress loader that displays the total loading percentage of all items being loaded.


Get Adobe Flash player


Demo Version, ask rx not actual component

Before we get into the LoaderCollection, health visit let’s discuss how you load single external files. The LoaderCollection recognizes Flash’s Loader class as well as a custom class called SimpleLoader.

The SimpleLoader:
The process of loading an external file such as an SWF or Bitmap file is as follows.
1. Import the SimpleLoader class, store I know it is not really that simple.
2. Create a new instance of SimpleLoader passing a minimum of 2 arguments.
A: parentObject (required): once the file is loaded, it will be added as a child to this object – parentObject.addChild(loadedObject);
B: contentURL (required): url path to the file to be loaded
C: objectName: the name you will use to target the loaded object – parentObject[objectName].width; available on load complete.
D: monitorFunction: a callback function were all loading progress is sent. – returns percent:int (0 – 100) and tag:String
E: tagString: A string to use as display text or unique id when multiple items are loaded.
3. Add a function to receive loader progress, expects percent:int and tag:String.

Usage Example:

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import com.hdi.loaders.LoaderCollection;
 
/** loading an external asset using SimpleLoader **/
 
//reserve the object name for the loaded object - optional.
var myLoadingSWF:Object;
 
/**
* new SimpleLoader
* @param parentObj: parent for loaded item - required
* @param contentURL: url path of content to load - required
* @param objectName: the target name of the final loaded object
* @param monFunction: function to callback with loader progress
* @param tagString: description or label of currently loading item - loader display text
**/
var loader:SimpleLoader = new SimpleLoader(this,"mySWF.swf", "myLoadingSWF", simpleLoaderCallback, "SWF");
 
//loading monitor function - expects percentage (0 - 100), tag (string)
function simpleLoaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc);
trace("Loading Tag: " + tag);
 
if(perc == 100){
trace("Loading Complete");
trace("Loaded Item Reference: " + myLoadingSWF.name);
}
}

Note: There are two options for targeting objects once they are loaded. ex: parentObject[objectName].width or parentObject.objectName.width. For the latter format to work, you must add a place holder object reference like so: var objectName:Object;

The Class:

?View Code ACTIONSCRIPT
package com.hdi.loaders{
 
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.ProgressEvent;
 
public class SimpleLoader{
 
public var url:String;								//url string
public var callback:Function = null;				//callback function or loading monitor - returns @percent (int 0 - 100), @tag (String from SimpleLoader)
public var tag:String = "";							//tag string of loading item
public var objName:String;							//object name for final loaded object
public var objParent:Object;						//parent for final loaded object
public var percent:int;								//percentage of loaded content
private var ldr:Loader;								//loader class
 
/**
* init
* @param parentObj: parent for loaded item
* @param contentURL: url path of content to load
* @param objectName: the target name of the final loaded object
* @param monFunction: function to callback with loader progress
* @param tagString: description or label of currently loading item
**/
public function SimpleLoader(parentObj:Object, contentURL:String, objectName:String = "", monFunction:Function = null, tagString:String = ""){
 
callback = monFunction;
url = contentURL;
objName = objectName;
objParent = parentObj;
tag = tagString;
 
//load items and setup event listener
ldr = new Loader();
ldr.load(new URLRequest(contentURL));
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingComplete);
ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadingProgress);
}
 
/**
* on loading complete
* @param event: Event
**/
private function loadingComplete(ev:Event):void{
 
//add item to parent and add object name
if(objParent != null){
var obj:Object = ev.target.content;
objParent.addChild(obj);
if(objName.length > 0){
objParent[objName] = obj;
}
ldr.unload();
}
 
//set percent to 100 and callback
percent = 100;
if(callback != null){
callback(100, tag);
}
 
//remove event listeners
if(ev.target.hasEventListener(Event.COMPLETE)){
ev.target.removeEventListener(Event.COMPLETE, loadingComplete);
}
if(ev.target.hasEventListener(ProgressEvent.PROGRESS)){
ev.target.removeEventListener(ProgressEvent.PROGRESS, loadingProgress);
}
}
 
/**
* on loading progress
* @param event: ProgressEvent
**/
private function loadingProgress(ev:ProgressEvent):void{
 
//update percent
percent = Math.floor((ev.bytesLoaded / ev.bytesTotal)*100);
if(callback != null){
 
//callback updated percentage
if(percent < 100){
callback(percent, tag);
}
}
}
}
}

The LoaderCollection:
To monitor the loading progress of multiple loading items at once, follow these steps:
1. Import the LoaderCollection Class
2. Create and instance of LoaderCollection passing a reference to the function that will be used to monitor loading progress.
3. Add each loader to the LoaderCollection, for best results do this in one frame

Usage Example (SimpleLoader):

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import com.hdi.loaders.LoaderCollection;
 
/** loading Multiple items using SimpleLoader **/
 
//reserve the object name for the loaded object - optional.
var myLoadingSWF:Object;
var myLoadingBMP:Object;
 
/**
* new LoaderCollection
* @param callback: funciton to call on loader updates
**/
var loaderManager:LoaderCollection = new LoaderCollection(loaderCallback);
 
// new SimpleLoaders
var loader1:SimpleLoader = new SimpleLoader(this,"mySWF.swf", "myLoadingSWF", null, "SWF");
var loader2:SimpleLoader = new SimpleLoader(this,"myBMP.jpg", "myLoadingBMP", null, "BMP");
 
//add Simple Loaders to LoaderCollection
loaderManager.addSimpleLoader(loader1);
loaderManager.addSimpleLoader(loader2);
 
//loading monitor function from LoaderCollection - expects percentage (0 - 100), tag (string)
function loaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc); //average loaded of all loading files
trace("Loading Tag: " + tag);	//tag name for display of one of the currently loading files.
 
if(perc == 100){
trace("Loading Complete"); // all items in the collection have been loaded, the LoaderCollection will no longer work at this point.
}
}

UsageExample (Loader):

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import flash.display.Loader;
 
/** loading Multiple items using flash.display.Loader **/
var loaderManager:LoaderCollection = new LoaderCollection(loaderCallback);
 
//create new loader and load files as normal.
var loader1:Loader = new Loader();
loader1.load(new URLRequest("myLoadingSWF.swf"));
addChild(loader1);
 
var loader2:Loader = new Loader();
loader2.load(new URLRequest("myLoadingBMP.jpg"));
addChild(loader2);
 
// add loaders to LoaderCollection
loaderManager.addLoader(loader1);
loaderManager.addLoader(loader2);
 
//loading monitor function from LoaderCollection - expects percentage (0 - 100), tag (string)
function loaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc); //average loaded of all loading files
trace("Loading Tag: " + tag);	//empty string when not using SimpleLoader.
 
if(perc == 100){
trace("Loading Complete"); // all items in the collection have been loaded, the LoaderCollection will no longer work at this point.
}
 
}
 
stop();

Note: Once the LoaderCollection reaches 100% all the functionality of the class is automatically disabled.

The Class:

?View Code ACTIONSCRIPT
package com.hdi.loaders{
 
import flash.events.Event;
import flash.display.Loader;
import flash.display.MovieClip
 
public class LoaderCollection extends MovieClip {
 
public var loaderList:Array = [];								//array of added loaders
private var callbackFunc:Function = null;						//function to callback on loader updates - returns @percent (int 0 - 100), @tag (String from SimpleLoader)
public var percent:int;											//@percent (int 0 - 100)
public var tag:String = "";										//@tag (String from SimpleLoader) currently loading item tag
var index:int;													//index of loading items in loaderList;
/**
* init
* @param callback: funciton to call on loader updates
**/
public function LoaderCollection(callback:Function):void{
callbackFunc = callback;
this.addEventListener(Event.ENTER_FRAME, loaderHandler);
}
 
/**
* add SimpleLoader instance to LoaderCollection
* @param loader: SimpleLoader
**/
public function addSimpleLoader(loader:SimpleLoader):void{
loaderList.push(loader);
}
 
/**
* add Loader instance to LoaderCollection
* @param loader: Loader
**/
public function addLoader(loader:Loader):void{
loaderList.push(loader);
}
 
/**
* stop loader updates and cleanup eventlisteners
**/
public function cleanup():void{
if(this.hasEventListener(Event.ENTER_FRAME)){
this.removeEventListener(Event.ENTER_FRAME, loaderHandler);
}
loaderList = [];						//reset loaderList
}
 
/**
* figure out average percent of all loading items
* @param event: Event
**/
private function loaderHandler(ev:Event):void{
//trace(this.name);
 
var perc:int = 0;						//average percent of loaded items
var ldrs:int = loaderList.length;		//number of currently loading items
var inc:int;							//percent loaded of loader
 
//has loading items
if(loaderList.length > 0){
 
var ldr:* = loaderList[index];			//loading item
 
// update tag if SimpleLoader
if(ldr is SimpleLoader){
tag = ldr.tag;
}
 
for(var p:String in loaderList){
ldr = loaderList[p];			//loading item
inc = 0;
 
//update percent increment
if(ldr is SimpleLoader){
inc = ldr.percent;
}
else{
if(ldr.contentLoaderInfo != null){
inc = Math.floor((ldr.contentLoaderInfo.bytesLoaded/ldr.contentLoaderInfo.bytesTotal)*100);
}
}
 
if(inc > percent && inc < 100){
index = int(p);
}
 
//update percentage
perc += inc;
 
//clear fully loaded items
if(inc == 100){
//loaderList.splice(int(p),1);
}
}
 
//update percentage and callback updated loading info
percent = Math.floor(perc/ldrs);
callbackFunc(percent, tag);
 
//cleanup Collection once all items are loaded
if(percent == 100){
cleanup();
}
}
}
}
}

Thanks for reading,
What are some other loading tips or components?

LoaderCollection:
Loading multiple files with a single progress loader that displays the total loading percentage of all items being loaded.

Demo Version, web not actual component

Before we get into the LoaderCollection, information pills let’s discuss how you load single external files. The LoaderCollection recognizes Flash’s Loader class as well as a custom class called SimpleLoader.

The SimpleLoader:
The process of loading an external file such as an SWF or Bitmap file is as follows.
1. Import the SimpleLoader class, tadalafil I know it is not really that simple.
2. Create a new instance of SimpleLoader passing a minimum of 2 arguments.
A: parentObject (required): once the file is loaded, it will be added as a child to this object – parentObject.addChild(loadedObject);
B: contentURL (required): url path to the file to be loaded
C: objectName: the name you will use to target the loaded object – parentObject[objectName].width; available on load complete.
D: monitorFunction: a callback function were all loading progress is sent. – returns percent:int (0 – 100) and tag:String
E: tagString: A string to use as display text or unique id when multiple items are loaded.
3. Add a function to receive loader progress, expects percent:int and tag:String.

Usage Example:

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import com.hdi.loaders.LoaderCollection;
 
/** loading an external asset using SimpleLoader **/
 
//reserve the object name for the loaded object - optional.
var myLoadingSWF:Object;
 
/**
* new SimpleLoader
* @param parentObj: parent for loaded item - required
* @param contentURL: url path of content to load - required
* @param objectName: the target name of the final loaded object
* @param monFunction: function to callback with loader progress
* @param tagString: description or label of currently loading item - loader display text
**/
var loader:SimpleLoader = new SimpleLoader(this,"mySWF.swf", "myLoadingSWF", simpleLoaderCallback, "SWF");
 
//loading monitor function - expects percentage (0 - 100), tag (string)
function simpleLoaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc);
trace("Loading Tag: " + tag);
 
if(perc == 100){
trace("Loading Complete");
trace("Loaded Item Reference: " + myLoadingSWF.name);
}
}

Note: There are two options for targeting objects once they are loaded. ex: parentObject[objectName].width or parentObject.objectName.width. For the latter format to work, you must add a place holder object reference like so: var objectName:Object;

The Class:

?View Code ACTIONSCRIPT
package com.hdi.loaders{
 
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.ProgressEvent;
 
public class SimpleLoader{
 
public var url:String;								//url string
public var callback:Function = null;				//callback function or loading monitor - returns @percent (int 0 - 100), @tag (String from SimpleLoader)
public var tag:String = "";							//tag string of loading item
public var objName:String;							//object name for final loaded object
public var objParent:Object;						//parent for final loaded object
public var percent:int;								//percentage of loaded content
private var ldr:Loader;								//loader class
 
/**
* init
* @param parentObj: parent for loaded item
* @param contentURL: url path of content to load
* @param objectName: the target name of the final loaded object
* @param monFunction: function to callback with loader progress
* @param tagString: description or label of currently loading item
**/
public function SimpleLoader(parentObj:Object, contentURL:String, objectName:String = "", monFunction:Function = null, tagString:String = ""){
 
callback = monFunction;
url = contentURL;
objName = objectName;
objParent = parentObj;
tag = tagString;
 
//load items and setup event listener
ldr = new Loader();
ldr.load(new URLRequest(contentURL));
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingComplete);
ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadingProgress);
}
 
/**
* on loading complete
* @param event: Event
**/
private function loadingComplete(ev:Event):void{
 
//add item to parent and add object name
if(objParent != null){
var obj:Object = ev.target.content;
objParent.addChild(obj);
if(objName.length > 0){
objParent[objName] = obj;
}
ldr.unload();
}
 
//set percent to 100 and callback
percent = 100;
if(callback != null){
callback(100, tag);
}
 
//remove event listeners
if(ev.target.hasEventListener(Event.COMPLETE)){
ev.target.removeEventListener(Event.COMPLETE, loadingComplete);
}
if(ev.target.hasEventListener(ProgressEvent.PROGRESS)){
ev.target.removeEventListener(ProgressEvent.PROGRESS, loadingProgress);
}
}
 
/**
* on loading progress
* @param event: ProgressEvent
**/
private function loadingProgress(ev:ProgressEvent):void{
 
//update percent
percent = Math.floor((ev.bytesLoaded / ev.bytesTotal)*100);
if(callback != null){
 
//callback updated percentage
if(percent < 100){
callback(percent, tag);
}
}
}
}
}

The LoaderCollection:
To monitor the loading progress of multiple loading items at once, follow these steps:
1. Import the LoaderCollection Class
2. Create and instance of LoaderCollection passing a reference to the function that will be used to monitor loading progress.
3. Add each loader to the LoaderCollection, for best results do this in one frame

Usage Example (SimpleLoader):

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import com.hdi.loaders.LoaderCollection;
 
/** loading Multiple items using SimpleLoader **/
 
//reserve the object name for the loaded object - optional.
var myLoadingSWF:Object;
var myLoadingBMP:Object;
 
/**
* new LoaderCollection
* @param callback: funciton to call on loader updates
**/
var loaderManager:LoaderCollection = new LoaderCollection(loaderCallback);
 
// new SimpleLoaders
var loader1:SimpleLoader = new SimpleLoader(this,"mySWF.swf", "myLoadingSWF", null, "SWF");
var loader2:SimpleLoader = new SimpleLoader(this,"myBMP.jpg", "myLoadingBMP", null, "BMP");
 
//add Simple Loaders to LoaderCollection
loaderManager.addSimpleLoader(loader1);
loaderManager.addSimpleLoader(loader2);
 
//loading monitor function from LoaderCollection - expects percentage (0 - 100), tag (string)
function loaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc); //average loaded of all loading files
trace("Loading Tag: " + tag);	//tag name for display of one of the currently loading files.
 
if(perc == 100){
trace("Loading Complete"); // all items in the collection have been loaded, the LoaderCollection will no longer work at this point.
}
}

UsageExample (Loader):

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import flash.display.Loader;
 
/** loading Multiple items using flash.display.Loader **/
var loaderManager:LoaderCollection = new LoaderCollection(loaderCallback);
 
//create new loader and load files as normal.
var loader1:Loader = new Loader();
loader1.load(new URLRequest("myLoadingSWF.swf"));
addChild(loader1);
 
var loader2:Loader = new Loader();
loader2.load(new URLRequest("myLoadingBMP.jpg"));
addChild(loader2);
 
// add loaders to LoaderCollection
loaderManager.addLoader(loader1);
loaderManager.addLoader(loader2);
 
//loading monitor function from LoaderCollection - expects percentage (0 - 100), tag (string)
function loaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc); //average loaded of all loading files
trace("Loading Tag: " + tag);	//empty string when not using SimpleLoader.
 
if(perc == 100){
trace("Loading Complete"); // all items in the collection have been loaded, the LoaderCollection will no longer work at this point.
}
 
}
 
stop();

Note: Once the LoaderCollection reaches 100% all the functionality of the class is automatically disabled.

The Class:

?View Code ACTIONSCRIPT
package com.hdi.loaders{
 
import flash.events.Event;
import flash.display.Loader;
import flash.display.MovieClip
 
public class LoaderCollection extends MovieClip {
 
public var loaderList:Array = [];								//array of added loaders
private var callbackFunc:Function = null;						//function to callback on loader updates - returns @percent (int 0 - 100), @tag (String from SimpleLoader)
public var percent:int;											//@percent (int 0 - 100)
public var tag:String = "";										//@tag (String from SimpleLoader) currently loading item tag
var index:int;													//index of loading items in loaderList;
/**
* init
* @param callback: funciton to call on loader updates
**/
public function LoaderCollection(callback:Function):void{
callbackFunc = callback;
this.addEventListener(Event.ENTER_FRAME, loaderHandler);
}
 
/**
* add SimpleLoader instance to LoaderCollection
* @param loader: SimpleLoader
**/
public function addSimpleLoader(loader:SimpleLoader):void{
loaderList.push(loader);
}
 
/**
* add Loader instance to LoaderCollection
* @param loader: Loader
**/
public function addLoader(loader:Loader):void{
loaderList.push(loader);
}
 
/**
* stop loader updates and cleanup eventlisteners
**/
public function cleanup():void{
if(this.hasEventListener(Event.ENTER_FRAME)){
this.removeEventListener(Event.ENTER_FRAME, loaderHandler);
}
loaderList = [];						//reset loaderList
}
 
/**
* figure out average percent of all loading items
* @param event: Event
**/
private function loaderHandler(ev:Event):void{
//trace(this.name);
 
var perc:int = 0;						//average percent of loaded items
var ldrs:int = loaderList.length;		//number of currently loading items
var inc:int;							//percent loaded of loader
 
//has loading items
if(loaderList.length > 0){
 
var ldr:* = loaderList[index];			//loading item
 
// update tag if SimpleLoader
if(ldr is SimpleLoader){
tag = ldr.tag;
}
 
for(var p:String in loaderList){
ldr = loaderList[p];			//loading item
inc = 0;
 
//update percent increment
if(ldr is SimpleLoader){
inc = ldr.percent;
}
else{
if(ldr.contentLoaderInfo != null){
inc = Math.floor((ldr.contentLoaderInfo.bytesLoaded/ldr.contentLoaderInfo.bytesTotal)*100);
}
}
 
if(inc > percent && inc < 100){
index = int(p);
}
 
//update percentage
perc += inc;
 
//clear fully loaded items
if(inc == 100){
//loaderList.splice(int(p),1);
}
}
 
//update percentage and callback updated loading info
percent = Math.floor(perc/ldrs);
callbackFunc(percent, tag);
 
//cleanup Collection once all items are loaded
if(percent == 100){
cleanup();
}
}
}
}
}

Thanks for reading,
What are some other loading tips or components?

Get Adobe Flash player

LoaderCollection:
Loading multiple files with a single progress loader that displays the total loading percentage of all items being loaded.

Demo Version, doctor not actual component

Before we get into the LoaderCollection, let’s discuss how you load single external files. The LoaderCollection recognizes Flash’s Loader class as well as a custom class called SimpleLoader.

The SimpleLoader:
The process of loading an external file such as an SWF or Bitmap file is as follows.
1. Import the SimpleLoader class, I know it is not really that simple.
2. Create a new instance of SimpleLoader passing a minimum of 2 arguments.
A: parentObject (required): once the file is loaded, it will be added as a child to this object – parentObject.addChild(loadedObject);
B: contentURL (required): url path to the file to be loaded
C: objectName: the name you will use to target the loaded object – parentObject[objectName].width; available on load complete.
D: monitorFunction: a callback function were all loading progress is sent. – returns percent:int (0 – 100) and tag:String
E: tagString: A string to use as display text or unique id when multiple items are loaded.
3. Add a function to receive loader progress, expects percent:int and tag:String.

Usage Example:

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import com.hdi.loaders.LoaderCollection;
 
/** loading an external asset using SimpleLoader **/
 
//reserve the object name for the loaded object - optional.
var myLoadingSWF:Object;
 
/**
* new SimpleLoader
* @param parentObj: parent for loaded item - required
* @param contentURL: url path of content to load - required
* @param objectName: the target name of the final loaded object
* @param monFunction: function to callback with loader progress
* @param tagString: description or label of currently loading item - loader display text
**/
var loader:SimpleLoader = new SimpleLoader(this,"mySWF.swf", "myLoadingSWF", simpleLoaderCallback, "SWF");
 
//loading monitor function - expects percentage (0 - 100), tag (string)
function simpleLoaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc);
trace("Loading Tag: " + tag);
 
if(perc == 100){
trace("Loading Complete");
trace("Loaded Item Reference: " + myLoadingSWF.name);
}
}

Note: There are two options for targeting objects once they are loaded. ex: parentObject[objectName].width or parentObject.objectName.width. For the latter format to work, you must add a place holder object reference like so: var objectName:Object;

The Class:

?View Code ACTIONSCRIPT
package com.hdi.loaders{
 
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.events.ProgressEvent;
 
public class SimpleLoader{
 
public var url:String;								//url string
public var callback:Function = null;				//callback function or loading monitor - returns @percent (int 0 - 100), @tag (String from SimpleLoader)
public var tag:String = "";							//tag string of loading item
public var objName:String;							//object name for final loaded object
public var objParent:Object;						//parent for final loaded object
public var percent:int;								//percentage of loaded content
private var ldr:Loader;								//loader class
 
/**
* init
* @param parentObj: parent for loaded item
* @param contentURL: url path of content to load
* @param objectName: the target name of the final loaded object
* @param monFunction: function to callback with loader progress
* @param tagString: description or label of currently loading item
**/
public function SimpleLoader(parentObj:Object, contentURL:String, objectName:String = "", monFunction:Function = null, tagString:String = ""){
 
callback = monFunction;
url = contentURL;
objName = objectName;
objParent = parentObj;
tag = tagString;
 
//load items and setup event listener
ldr = new Loader();
ldr.load(new URLRequest(contentURL));
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingComplete);
ldr.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loadingProgress);
}
 
/**
* on loading complete
* @param event: Event
**/
private function loadingComplete(ev:Event):void{
 
//add item to parent and add object name
if(objParent != null){
var obj:Object = ev.target.content;
objParent.addChild(obj);
if(objName.length > 0){
objParent[objName] = obj;
}
ldr.unload();
}
 
//set percent to 100 and callback
percent = 100;
if(callback != null){
callback(100, tag);
}
 
//remove event listeners
if(ev.target.hasEventListener(Event.COMPLETE)){
ev.target.removeEventListener(Event.COMPLETE, loadingComplete);
}
if(ev.target.hasEventListener(ProgressEvent.PROGRESS)){
ev.target.removeEventListener(ProgressEvent.PROGRESS, loadingProgress);
}
}
 
/**
* on loading progress
* @param event: ProgressEvent
**/
private function loadingProgress(ev:ProgressEvent):void{
 
//update percent
percent = Math.floor((ev.bytesLoaded / ev.bytesTotal)*100);
if(callback != null){
 
//callback updated percentage
if(percent < 100){
callback(percent, tag);
}
}
}
}
}

The LoaderCollection:
To monitor the loading progress of multiple loading items at once, follow these steps:
1. Import the LoaderCollection Class
2. Create and instance of LoaderCollection passing a reference to the function that will be used to monitor loading progress.
3. Add each loader to the LoaderCollection, for best results do this in one frame

Usage Example (SimpleLoader):

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import com.hdi.loaders.LoaderCollection;
 
/** loading Multiple items using SimpleLoader **/
 
//reserve the object name for the loaded object - optional.
var myLoadingSWF:Object;
var myLoadingBMP:Object;
 
/**
* new LoaderCollection
* @param callback: funciton to call on loader updates
**/
var loaderManager:LoaderCollection = new LoaderCollection(loaderCallback);
 
// new SimpleLoaders
var loader1:SimpleLoader = new SimpleLoader(this,"mySWF.swf", "myLoadingSWF", null, "SWF");
var loader2:SimpleLoader = new SimpleLoader(this,"myBMP.jpg", "myLoadingBMP", null, "BMP");
 
//add Simple Loaders to LoaderCollection
loaderManager.addSimpleLoader(loader1);
loaderManager.addSimpleLoader(loader2);
 
//loading monitor function from LoaderCollection - expects percentage (0 - 100), tag (string)
function loaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc); //average loaded of all loading files
trace("Loading Tag: " + tag);	//tag name for display of one of the currently loading files.
 
if(perc == 100){
trace("Loading Complete"); // all items in the collection have been loaded, the LoaderCollection will no longer work at this point.
}
}

UsageExample (Loader):

?View Code ACTIONSCRIPT
import com.hdi.loaders.SimpleLoader;
import flash.display.Loader;
 
/** loading Multiple items using flash.display.Loader **/
var loaderManager:LoaderCollection = new LoaderCollection(loaderCallback);
 
//create new loader and load files as normal.
var loader1:Loader = new Loader();
loader1.load(new URLRequest("myLoadingSWF.swf"));
addChild(loader1);
 
var loader2:Loader = new Loader();
loader2.load(new URLRequest("myLoadingBMP.jpg"));
addChild(loader2);
 
// add loaders to LoaderCollection
loaderManager.addLoader(loader1);
loaderManager.addLoader(loader2);
 
//loading monitor function from LoaderCollection - expects percentage (0 - 100), tag (string)
function loaderCallback(perc:int, tag:String):void{
trace("Percentage Loaded: " + perc); //average loaded of all loading files
trace("Loading Tag: " + tag);	//empty string when not using SimpleLoader.
 
if(perc == 100){
trace("Loading Complete"); // all items in the collection have been loaded, the LoaderCollection will no longer work at this point.
}
 
}
 
stop();

Note: Once the LoaderCollection reaches 100% all the functionality of the class is automatically disabled.

The Class:

?View Code ACTIONSCRIPT
package com.hdi.loaders{
 
import flash.events.Event;
import flash.display.Loader;
import flash.display.MovieClip
 
public class LoaderCollection extends MovieClip {
 
public var loaderList:Array = [];								//array of added loaders
private var callbackFunc:Function = null;						//function to callback on loader updates - returns @percent (int 0 - 100), @tag (String from SimpleLoader)
public var percent:int;											//@percent (int 0 - 100)
public var tag:String = "";										//@tag (String from SimpleLoader) currently loading item tag
var index:int;													//index of loading items in loaderList;
/**
* init
* @param callback: funciton to call on loader updates
**/
public function LoaderCollection(callback:Function):void{
callbackFunc = callback;
this.addEventListener(Event.ENTER_FRAME, loaderHandler);
}
 
/**
* add SimpleLoader instance to LoaderCollection
* @param loader: SimpleLoader
**/
public function addSimpleLoader(loader:SimpleLoader):void{
loaderList.push(loader);
}
 
/**
* add Loader instance to LoaderCollection
* @param loader: Loader
**/
public function addLoader(loader:Loader):void{
loaderList.push(loader);
}
 
/**
* stop loader updates and cleanup eventlisteners
**/
public function cleanup():void{
if(this.hasEventListener(Event.ENTER_FRAME)){
this.removeEventListener(Event.ENTER_FRAME, loaderHandler);
}
loaderList = [];						//reset loaderList
}
 
/**
* figure out average percent of all loading items
* @param event: Event
**/
private function loaderHandler(ev:Event):void{
//trace(this.name);
 
var perc:int = 0;						//average percent of loaded items
var ldrs:int = loaderList.length;		//number of currently loading items
var inc:int;							//percent loaded of loader
 
//has loading items
if(loaderList.length > 0){
 
var ldr:* = loaderList[index];			//loading item
 
// update tag if SimpleLoader
if(ldr is SimpleLoader){
tag = ldr.tag;
}
 
for(var p:String in loaderList){
ldr = loaderList[p];			//loading item
inc = 0;
 
//update percent increment
if(ldr is SimpleLoader){
inc = ldr.percent;
}
else{
if(ldr.contentLoaderInfo != null){
inc = Math.floor((ldr.contentLoaderInfo.bytesLoaded/ldr.contentLoaderInfo.bytesTotal)*100);
}
}
 
if(inc > percent && inc < 100){
index = int(p);
}
 
//update percentage
perc += inc;
 
//clear fully loaded items
if(inc == 100){
//loaderList.splice(int(p),1);
}
}
 
//update percentage and callback updated loading info
percent = Math.floor(perc/ldrs);
callbackFunc(percent, tag);
 
//cleanup Collection once all items are loaded
if(percent == 100){
cleanup();
}
}
}
}
}

Thanks for reading,
What are some other loading tips or components?

UPDATE 1.20, generic 4/21/11 : new source files below

Animation is the primary reason our clients choose Flash based applications over HTML or any other language. Creating applications that dance is the “Rich” in RIA development.

Great animation or tween engines are plenty, search GTween, order TweenLite and Tweener are just a few. They provide a simpler way of animating with code. The Flash IDE team has also gone to great lengths to make working with animation in code easier for the designers. Even Flash Builder 4, which one could argue is a programmers tool, has new animation classes that are far more powerful than their predecessors.


Interactive Demos below…

Animation is what makes Flash, Flash:
MoveThis has been around in many different forms as my personal tween engine for the last 8 years. I think it’s finally in a condition that it can be shared. The idea has always been one line of code to make something move, it’s extremely simple to use, yet supports many great features.

This latest incarnation has focused on performance. Something that would work great for building mobile applications. It isn’t perfect, or the only solution, but it works with my approach to building applications and games that require a great deal of animation.

Most tween engines work on the theory that a tween is something to keep around and run backwards and forwards, something like a video file with a play and pause function. MoveThis is based on an idea that there are so many tweens in an application, trying to manage pausing, reversing, playing and completion events gets too complicated or resource heavy.

Using MoveThis has 4 requirements:
1. know the display object to move.
2. know which property of the display object to animate.
3. know that target value of the display object property.
4. know how many frames the tween will span.

The resulting code looks like this:

?View Code ACTIONSCRIPT
MoveThis.startTween(foo,{x:500},30);

…which animates the x property of “foo” to a value of 500 over 30 frames. There are no start methods to call or instances to manage. Once the tween is complete it is nulled out and garbage collected.

Performance:
MoveThis is fairly light and very good on performance. MoveThis can run about 5000 tweens simultaneously at 24 frames per second and create *6500 new tweens in 1 second at 20 frames per second. MoveThis will add about 9k to your application.

*Note: One of the benefits of MoveThis is that it eliminates duplicate tweens, this constant cleaning can cause performance lags when adding a large amount ( > 250 ) of tweens on one frame. To get the type of performance claimed above, set ignoreDupes to true.

?View Code ACTIONSCRIPT
MoveThis.ignoreDupes = true;

Pros:
MoveThis uses 1 EventListener for all tweens, also onComplete, onStart and onFrame events use callbacks instead of Events which is better for mobile application performance. Optimized to work with thousands of tweens without worrying about duplicates or stopping tweens.

Cons:
Maybe not the best solution for a project with just a few animations that need to loop, stop, pause, play and rewind.

Now lets talk features!

Standard Features:
1. MoveThis is frame based, I have found that even the Timer class is not consistent from client to client based on processor speed, so we might as well use frames which is more accustom to animation. At some point I may add getTime and audio syncing.

2. onComplete, onStart, onFrame as callbacks instead of events, which preserves performance. Returns a references to the object being animated.

3. The pause tween: for when you want to call a function later, after a few frames, again without adding new events or timers.

4. visible = true: if something is animating, then it is probably meant to be seen, MoveThis automatically turns the visible property to true when the tween begins. (can be overridden)

5. One tween per object property at a time: This is one of the main reason MoveThis was created the way it was. Users changes there minds without waiting for tweens to complete. MoveThis will replace older, in progress tweens with a new one, picking up where the last tween left off.

6. Plugins: animate non-numeric properties, such as matrix, color, brightness, volume with custom plugins. (color and brightness plugins included)

7. queue tweens: when limiting one tween per property at a time, tweens can be queued for later, without overwriting a current tween. Just like startTween, except the first argument sets how many frames the tween will remain in the queue.

?View Code ACTIONSCRIPT
MoveThis.queueTween(30, foo,{x:500},30);

8. pause: pause a current tween or all tweens

9. stop an individual tween or stop all current tweens for each display object.

10. When a tween is completed it is nulled out, freeing up memory for other stuff.

11: based on standard easing functions: includes Reverse and Arch easing functions, as well as, standard easing functions by Robert Penner.

How it Works:
Arguments:
1. targObject: (Object) A reference to the object that is to be animated.
2. propValues: (Object) An object containing all the numeric properties or plugins of the object that are to be tweened.
3. frames: (int) The amount of frames the tweens will span.
4. extras: (Object) Many features such as onComplete, easingFunction, loop and delay are set in the extras object.

?View Code ACTIONSCRIPT
MoveThis.startTween(foo,{x:500},30,{onComplete:completeHandler,easing:"Sine.EaseIn",delay:30});


Get Adobe Flash player


Extras (and how they work):
1. delay: (int) the frame count before the tween starts.

2. ease: (Number, 0 – 1) Adds an ease percentage to any easing function. designers like to add verity and subtlety to their animations, easing functions are no longer all or nothing.

3. easingFunction: (Function) Use standard or custom easing functions.

4. easing: (String, “Bounce.easeIn” ) Standard easing functions can be declared as a string, which elevates the need to import easing classes which helps in testing out a few different easing functions, trying to find that perfect ease.

5. loop: (Boolean) An animations can loop infinitely or just a few times.

6. visibility: (Boolean, false) Sets an object’s visible property to false after a tween.

7. startVisible: (Boolean, false) Override the default behavior of automatically setting an object’s visible property to true on the first frame of the tween.

8. remove: (Boolean) Automatically remove a display object or element after the tween is completed.

9. uid: (int ) A unique identifier, used for pause tweens, so they can be overwritten.

10. onStart, onFrame, onComplete: (Function) Callback functions, returns a reference to the animated object.

11. smartRotation: (Boolean) Forces the tween to rotate in the direction of the closest angle.

12. removeDupes: (Boolean, true) Default behavior is to remove all duplicates, but to save performance, you may want to turn this feature off and manage it on a per tween basis.

One Tween at a time:
Not to be stuck in an endless loop here, but this has a huge impact of how MoveThis is used, so one last time; I promise. Once a tween is completed in the MoveThis engine, it is removed and nulled out. If you need to reverse a tween or replay a previous tween, the best procedure is to start a new tween. MoveThis only allows one tween per property per object to occur at a time. If a tween is started on the x property of a displayObject named foo over 30 frames, when another tween is started just a few frames later for the same object’s x property, the first tween will be replaced by the new tween. Once the new tween is finished, it will be removed forever, unless a loop count was added.

One Tween for each property:
When a tween is started, an object (MoveThisObject) is created for each property to be animated. Each tween object is then animated separately. This allows you to start one tween with multiple properties, then update the animation by starting a new tween with of single property value.

Example:

?View Code ACTIONSCRIPT
//initial tween
MoveThis.startTween(foo,{x:500,y:400,:alpha:1},30);
 
//something in our app changes, that require foo to fade out.
MoveThis.startTween(foo,{alpha:0},30);

The x and y properties will continue to tween while the alpha property tween for foo will be replaced and the new fade out tween will began.

The repercussions are that if you have onComplete, onStart, onFrame callbacks assigned to that tween, the callbacks will be called for each property. In the following example, the function “completeHandler” will be called twice, once on complete of the x tween and once on the complete of the y tween.

Example:

?View Code ACTIONSCRIPT
MoveThis.startTween(foo,{x:500,y:400,:alpha:1},30,{onComplete:completeHandler);

Three Ways to Make Things Happen Later:
1. delay: The simplest way to delay a tween.

?View Code ACTIONSCRIPT
//wait 20 frames before starting
MoveThis.startTween(foo,{x:500},30,{delay:20});

Note: If this is used and another tween is added for the x property of foo, it will be replaced, even if the delay has not expired

2. queueTween: When you know you want to move something later, but do not want it to overwrite a current tween.

?View Code ACTIONSCRIPT
//queue this tween for 30 frames
MoveThis.queueTween(30,foo,{x:500});

Note: Once the queue time is complete, the queued tween will replace any existing tweens for the same property of the same object.

3. The pause tween: Used when you want to call a function after a certain number of frames. Easier and requires less processor than using the Timer class.

?View Code ACTIONSCRIPT
//call pauseHandler after 90 frames.
MoveThis.startTween(null,{pause:90},0,{onComplete:completeHandler});

Note: Frame count is ignored. The pause tween must include an onComplete function.

Note: Replace null with a displayObject reference to have that reference sent to the onComplete function.

Unique ID: By default all pause tweens are persistent, meaning duplicates for the pause property are allowed to exist. If you need to overwrite a pause tween, then give the tween a unique id, when a new pause tween is created with the same id, it will overwrite the previous one.

?View Code ACTIONSCRIPT
MoveThis.startTween(null,{pause:90},0,{onComplete:completeHandler,uid:1});

onComplete Function Example:

?View Code ACTIONSCRIPT
function completeHandler(obj:Object):void{
//all target references are returned as objects.
//this allows you to start a new animation or modify the target when the animation is completed
if(obj != null)
obj.visible = false;
}

Easing:
Easing works very similar to all the existing tween/animation engines and works with any standardized easing functions. There are three ways to add eases to your animation.

1. easingFunction: This is the most typical ways of adding ease to a tween. Add a reference to any standardized easing function and you are done.

?View Code ACTIONSCRIPT
//add Sine.easeOut as the easingFunction. (the Sine.EaseOut class must be imported first)
MoveThis.startTween(foo,{x:500},30,{easingFunction:Sine.easeOut});

2. easing: An alternate method of #1 and for lazy people like me or someone that wants to try out a few different easing functions without importing them all. Enter one of the included standard tween function names as a string and MoveThis imports the correct easing function for you.

?View Code ACTIONSCRIPT
//add Sine.easeOut as the easingFunction without importing the class
MoveThis.startTween(foo,{x:500},30,{easing:"Sine.easeOut"});

3. easingStrength: Not every easing function has to be 100% all or nothing. Adding a 0 – 1 value will allow you to have a little less ease if needed.

?View Code ACTIONSCRIPT
//add Quart.easeOut as the easingFunction with only 60% ease.
MoveThis.startTween(foo,{x:500},30,{easing:"Quart.easeOut",easingStrength:0.6});

4. ease: Works just like the Flash IDE, set ease from -1 to 1 to automatically add Sine.easeOut or Sine.easeIn, depending on the value.

?View Code ACTIONSCRIPT
//add Sine.easeIn as the easingFunction with only 60% ease.
MoveThis.startTween(foo,{x:500},30,{ease:-0.6});

Note: There are two easing classes included to enable looping animations that reverse before looping again. (Arch.linear, Arch.easeIn, Arch.easeOut, Reverse.linear, Reverse.easeIn, Reverse.easeOut, Reverse.easeInOut, Reverse.easeOutIn)

Easing Demo:


Get Adobe Flash player


Visibility and Remove:
By default all tweened objects are made visible on frame one of a tween. You can override this functionality by adding startVisible:false to the extras.

?View Code ACTIONSCRIPT
//the object will not automatically turn visible on frame 1 of the tween
MoveThis.startTween(foo,{x:500},30,{startVisible:false});
<pre>
 
MoveThis will also set the visible property to false after a tween is complete or remove that object from the display list. These two features are extremely effective ways to free up memory.
 
<pre lang="actionscript">
//the object's visible property will be set to false at the end of the tween.
MoveThis.startTween(foo,{x:500},30,{visible:false});
 
//the object will be removed from the display list on complete of the tween
MoveThis.startTween(foo,{x:500},30,{remove:true});

Pause and Stop:
Pause and Stop only work on tweens that currently exist in the MoveThis engine. You can make a call to MoveThis to pause or stop a particular tween or you can and stop all the existing tweens for a particular object.

?View Code ACTIONSCRIPT
//finds a tween for the object "foo" and the property "x"
MoveThis.stopTween(foo,"x");
 
//finds all tweens for the object "foo" and stops them
MoveThis.stopAllTweens(foo");
 
//pauses an existing tween for the x property of the object "foo"
MoveThis.pauseTween(foo,"x",true);
 
//resumes an existing tween for the x property of the object "foo"
MoveThis.pauseTween(foo,"x",false);

You can also pause MoveThis using MoveThis.pause(true);

Plugins:
Plugins are a great way to add functionality and new tween-able properties to objects. Included are a couple classes to animate the color or brightness of an object. Plugins can be installed at runtime.

?View Code ACTIONSCRIPT
var plugin:Object = {brightness: com.hdi.animate.Brightness};
MoveThis.install(plugin);

The installedPlugins property of MoveThis is an array of all the currently installed plugins.

?View Code ACTIONSCRIPT
var plugins:Array =  MoveThis.installedPlugins; // [returns an array or objects]

Working with Flex 4 SDK:
To use MoveThis with Flex 4’s Group and Element classes, uncomment 3 snippets of code from com.hdi.animation.MoveThisEngine, to enable remove functionality. (sample snippet)

?View Code ACTIONSCRIPT
/***************************************************************
* FLEX 4 SDK: UNCOMMENT FOR Group and Element support (2 of 3)
***************************************************************/
/*
try{
moveObj.targetObj.parent.removeElement(moveObj.targetObj as IVisualElement);
}
catch(e:Error){}
*/
/*** END FLEX 4 SDK ********************************************/

UPDATE 1.20, 4/21/11 :

Updated code to run a little faster, using while loops instead of for each loops.
Added Sound or Mixer volume plugin to fade volume in and out.
Added methods for stopping queued animations

Download Complete Source Files

What tween engines do you like to use and why?

Artists through the ages have pushed the limits and innovated new mediums to communicate to the world. Color has always played a huge roll of how art was received. In this chapter in the Illustrating with Illustrator series, tadalafil we will discuss color and the different ways to apply color to our work.

Color Schemes:
Color schemes are two or more colors that are used to identify a message or reinforce a brand. A color scheme normally consists of at least a primary and secondary color. Not to be confused with a painter’s primary colors red, information pills yellow and blue, look a primary color is the dominant color in the color scheme and can be any color.

There are many methods to developing strong color schemes, from collecting paint chips at the local hardware store to using applications such as Adobe Kuler. Most of the time we are given a brand identity that contains a complete color scheme or becomes a starting point for developing a new one. Illustrator’s Color Panel is a great tool to create limitless combinations of hue and saturation providing the perfect mood and tone of our message.


Colors From Our Past:

more color ideas @ http://dynamicgraphics.com/.

The Color Palette
This was not intended to be a lesson in color theory, so I’m skipping all the color wheel, complimentary color and duo-tone lectures. The point of this post, put simply, Illustrator has some great color tools and you should use them to build custom color palettes for your illustrations.

Start out creating a rectangle filled with each color in the color scheme, then add rectangles for all the other colors you will need for your illustration like the grid below. The process is kind of like making your own box of square crayons.



Grid of psychedelic color scheme from above.



Dark blue and Green added.

Making Shadows and Highlights:
Copy the main color row to a new row on top, we will call this the shadow row. Set the Color Panel mode to HSB, then select each color and slide the B slider to the left. Sliding the B slider to the right, which makes the color brighter, may work for some colors, but most likely a different approach is needed. Change the Color Panel mode to RGB, select each swatch you would like to make lighter, hold the Shift Key and drag one of the color channel sliders to the right until you get the desired shade. You should notice the other 2 sliders moving as well. The Shift key only helps maintain the general hue, when Shift dragging to the right, the color becomes less saturated, while Shift dragging to the left produces more saturated hues. To get the desired saturation, you can ether tweak the RGB channels or set the Color Panel mode back to HSB and adjust the saturation slider.



Shadow and Highlight Rows added.


Switching from RGB to HSB mode

Add as many shades of each color you need for the illustration.

Color Harmony:
Many artists create colors on the fly which seems so much easier, so why would I suggest taking so much extra time to create color palettes? Two reasons:

1. Say you work with a team of artists and the artwork needs to look unified. Share the color palette as Swatch Library or template Illustrator file and everyone can work from the same colors.

2. Color Harmony, think vocal harmonies, some voices just don’t work together, the same holds true for hues and saturations of color. Creating a color palette in the grid form shown above confirms that all your colors are in harmony.



Same general colors, but very offensive to the eye, definitely not in harmony.

The Wash:
There is a painters trick called a wash that is used to bring all their colors into harmony or to reenforce the color mood of a painting. The painter takes a color and thins it way down, then brushes this thin layer of color over the areas of the painting where the hue is needed. Using a bright yellow wash could set the mood of the morning sun. A blue wash could unify all the colors in an underwater scene while using red could give the impression of heat. For a painting, a painter uses this technique at the end of the process, in the computer illustration we can choose to incorporate this trick throughout the process.

To use the wash technique on the color palette:
1. Finish adding all the colors of the color palette and bringing them into harmony

2. Make a copy of all the squares, you may want to apply multiple color washes for different color moods, plus it’s always good to have a backup.



Full Psychedelic Color Palette with all hues and saturations in harmony.

3. Create a shape over the colored areas you want effected by the wash. For a color palette, a rectangle over all the colored squares will do it.

4. Fill the shape the color you want to use.



Blue overlay R: 0, G: 164, B: 228

5. With the rectangle selected, goto the Transparency Panel and change the blend mode from Normal, to Overlay, Hard Light, Hue or Color, which ever gives you the best results. Adjust the transparency setting to get the exact amount of wash effect on all the colors.



Transparency Panel Settings: Layer Mode: Color, Opacity: 35

6. Select all the colored squares including the transparent rectangle on top. Goto Object: Flatten Transparency… In the settings window that pops up, slide the Raster/Vector Balance slider all the way to 100, on the vector side (right). The rest of the settings should be fine, you can check the preview box to make sure.




7. All the squares will now have a solid color fill that matches the washed color. There will be some odd colored squares behind the visible colored squares, if you are a neat freak like me, you may want to get rid of them, otherwise they will no hurt anything.



Final Palette with new yellow column added.



Illustration sample using blue washed psychedelic color palette.

To use the wash technique during or at the end of the illustration process:
Apply steps 3 – 5 above to any elements of the illustration where a more unified color is desired.

Tip: Colors in the Color panel can be saved as Swatch Libraries.

Tip: Double-Click swatches to give them a name and modify swatch type.

Tip: Spot Color swatches used in an illustration are globally adjusted when the color swatch color values are adjusted in the Color Panel.

Coming soon, Illustrating In Illustrator Part 5 of 5: Textures and Effects.

Technorati Tags: , , , , , , , , ,

Leave a Reply