Robotlegs, Part 2: Adding ImageLoader & TweenMax

Expanding on the previous Robotlegs entry. The original source code is generously provided by hubflanger. I’m modifying her code to show images using two popular asset loading & animation libraries. To do this we have to modify the XML data file and image preloading, processing & display code in these 3 classes: LoaderMaxDataService, SectionVO & SectionContainer.

Updated LoaderMaxDataService:

package com.hubflanger.robotlegsdemo.service
{
	import com.hubflanger.robotlegsdemo.model.vo.SectionVO;
	import com.hubflanger.robotlegsdemo.model.SiteModel;
	import com.hubflanger.robotlegsdemo.events.SystemEvent;
	
	import com.greensock.events.LoaderEvent;
	import com.greensock.loading.ImageLoader;
	import com.greensock.loading.LoaderMax;
	import com.greensock.loading.XMLLoader;
	import com.greensock.loading.display.ContentDisplay;
	
	import flash.events.Event;
	import flash.net.*;
	
	import org.robotlegs.mvcs.Actor;
		
	/**
	 * A Service class that handles loading and parsing of the site's xml data.
	 */	
	public class LoaderMaxDataService extends Actor implements ISiteDataService
	{
		/**
		 * Inject the <code>SiteModel</code> Singleton.
		 */		
		[Inject]
		public var model				:SiteModel; 		
		private var queue				:LoaderMax; 		
		private var xml					:XMLLoader;

		public function LoaderMaxDataService()
		{ 			
			LoaderMax.activate([XMLLoader, ImageLoader]);				
		}
				
		public function loadData():void 
		{			
			var xml:XMLLoader = new XMLLoader("assets/data.xml", 
											  {name:"mainXML", 
											  onComplete:xmlComplete, 
											  estimatedBytes:4000});
			xml.load();						
		}
		
		/**
		 * Handler for the XMLLoader's onComplete.	
		 * <p>Preloads the images</p>
		 */			
		private function xmlComplete(e:LoaderEvent):void
		{
			xml = e.target as XMLLoader; 
			
			queue = new LoaderMax({name:"mainQueue", 
								   onProgress:qProgressHandler,
								   onComplete:qCompleteHandler,
								   onError:qErrorHandler});

			var sections:XMLList = xml.content.sections.section; 			
			for each (var section:XML in sections) 
			{
				queue.append(new ImageLoader(section.img.@src, 
												 {name:"image_" + section.@id,											
												  alpha:0,
												  visible:false,											  											
												  container:this}));					
			}						
			
			queue.load();	
		}

		private function qProgressHandler(e:LoaderEvent):void 
        { 
            trace("progress: " + e.target.progress); 
        }
		private function qErrorHandler(e:LoaderEvent):void
        { 
            trace("qErrorHandler(): error occured with " + e.target + ": " + e.text); 
        } 
		private function qCompleteHandler(e:LoaderEvent):void 
		{
			trace(e.target + "queue complete");							
			imagesCompleteHandler();						
		}			
		 		 
		/**
		 * Process content data after images are preloaded.	
		 * <p> Tell the rest of the application when data is ready.</p>
		 */				 
		private function imagesCompleteHandler():void 
		{			
			model.header = xml.content.header.text(); 
			var sections:XMLList = xml.content.sections.section; 
			
			for each (var section:XML in sections) 
			{
				var sectionVO:SectionVO = new SectionVO(section.@id,
														section.label.toString(),
														LoaderMax.getContent("image_" + section.@id), 
														section.content.toString());				
				
				model.sectionsList.push(sectionVO);
				model.sectionsHash[sectionVO.id] = sectionVO;
			}			
			
			model.defaultSection = model.sectionsList[0].id;
			
			dispatch(new SystemEvent(SystemEvent.INIT_VIEW, false));					
		}				
	}
}

A few minor changes to SectionVO, to accomodate the new image property:

package com.hubflanger.robotlegsdemo.model.vo
{
	import com.greensock.loading.display.ContentDisplay;
	
	public class SectionVO
	{
		private var _id:String;
		private var _label:String;
		private var _image:ContentDisplay;
		private var _content:String;
		
		/**
		 * A custom  object for storing Section node data
		 */
		public function SectionVO( id:String, label:String, img:ContentDisplay, content:String )
		{
			_id = id;
			_label = label;
			_image = img;
			_content = content;
		}

		public function get id():String
		{
			return _id;
		}
		
		public function get label():String
		{
			return _label;
		}

		public function get image():ContentDisplay
		{
			return _image;
		}
		
		public function get content():String
		{
			return _content;
		}
	}
}

And finally, the addition of a Sprite image container & image display code with TweenMax:

package com.hubflanger.robotlegsdemo.view.components
{
	import com.greensock.TweenMax;

	import com.hubflanger.robotlegsdemo.model.vo.SectionVO;
	
	import flash.display.*;
	import flash.text.*;
	import flash.utils.Dictionary;
	
	/**
	 * The display container for the section content.
	 */	
	public class SectionContainer extends Sprite
	{
		private var sectionsHash:Dictionary = new Dictionary();
		private var textField:TextField;
		private var img:Sprite;
		
		/**
		 * The constructor. 
		 * <p>
		 * Creates a Shape object as background. Creates a TextField 
		 * for the content copy and a Sprite to hold images.
		 */	
		public function SectionContainer()
		{
			var bg:Shape = new Shape();
			bg.graphics.beginFill(0xF9E5C2);
			bg.graphics.drawRect(0, 0, 550, 400);
			bg.graphics.endFill();
			addChild(bg); 
				
			var tf:TextFormat = new TextFormat();
			tf.font = "Helvetica";
			tf.color = 0x4B1E18;
			tf.size = 12;
			
			textField = new TextField();
			textField.x = 222;
			textField.y = 81;
			textField.width = 310;
			textField.height = 290;
			textField.multiline = true;
			textField.wordWrap = true;
			textField.defaultTextFormat = tf;
			addChild(textField);
			
			img = new Sprite();
			img.x = 12;
			img.y = 95;
			addChild(img);			
		}
		
		/**
		 * Assigns a Dictionary object to the <code>sectionsHash</code> property.
		 *  
		 * @param hash A Dictionary instance containing <code>SectionVO</code>
		 * objects with Section IDs as key.
		 */		
		public function init(hash:Dictionary):void
		{
			sectionsHash = hash;
		}
		
		/**
		 * Retrieves the <code>SectionVO</code> object associated with the 
		 * Section ID and and populates the <code>textField</code> with the 
		 * value of its <code>content</code> property. Populates <code>img</code>
		 * with <code>SectionVO</code>'s value of <code>image</code>. 
		 *
		 * @param str The String ID of the Section selected.
		 */
		public function update(id:String):void
		{
			var sectionVO:SectionVO = sectionsHash[id];
			textField.htmlText = sectionVO.content;			

			cleanImgHolder(img);			
			img.addChild(sectionVO.image);
			TweenMax.to(sectionVO.image, 0.66, {autoAlpha:1});											
		}
		
		private function cleanImgHolder(i:Sprite):void 
		{
			if(i.numChildren > 0) { 
				TweenMax.to(i.getChildAt(0), 0, {autoAlpha:0});		
				i.removeChildAt(0);
			}
		}
	}
}

Don’t forget to update the XML file to contain an “img” element with an “src” attribute:

 <!-- ... -->
		<section id="home">
			<label>Home</label>
			<img src="images/1.jpg" />
			<content>
				<p>Lorem ipsum dolor sit amet...</p>
			</content>
		</section>
<!-- ... -->
Advertisements

3 thoughts on “Robotlegs, Part 2: Adding ImageLoader & TweenMax

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s