<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="http://feedproxy.google.com/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feedproxy.google.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>The Tech Labs</title>
	
	<link>http://www.thetechlabs.com</link>
	<description>Adobe Air, Flash and Flex Tutorials</description>
	<pubDate>Thu, 23 Oct 2008 22:58:12 +0000</pubDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
			<thespringbox:skin xmlns:thespringbox="http://www.thespringbox.com/dtds/thespringbox-1.0.dtd">http://feedproxy.google.com/TheTechLabs?format=skin</thespringbox:skin><media:copyright>All Rights Reserved</media:copyright><media:keywords>Tutorials,adobe,air,flash,flex,webdesign</media:keywords><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Technology/Software How-To</media:category><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Technology/Tech News</media:category><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Education/Training</media:category><media:category scheme="http://www.itunes.com/dtds/podcast-1.0.dtd">Education/Educational Technology</media:category><itunes:owner><itunes:email>webmaster@thetechlabs.com</itunes:email><itunes:name>The Tech Labs</itunes:name></itunes:owner><itunes:author>The Tech Labs</itunes:author><itunes:explicit>no</itunes:explicit><itunes:keywords>Tutorials,adobe,air,flash,flex,webdesign</itunes:keywords><itunes:subtitle>Adobe Air, Flash and Flex Tutorials</itunes:subtitle><itunes:summary>Adobe Air, Flash and Flex Tutorials</itunes:summary><itunes:category text="Technology"><itunes:category text="Software How-To" /></itunes:category><itunes:category text="Technology"><itunes:category text="Tech News" /></itunes:category><itunes:category text="Education"><itunes:category text="Training" /></itunes:category><itunes:category text="Education"><itunes:category text="Educational Technology" /></itunes:category><image><link>http://www.thetechlabs.com</link><url>http://www.thetechlabs.com/wp-content/uploads/2008/09/thetechlabs_feed.jpg</url><title>The Tech Labs</title></image><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feedproxy.google.com/TheTechLabs" type="application/rss+xml" /><feedburner:emailServiceId>TheTechLabs</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeedproxy.google.com%2FTheTechLabs" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeedproxy.google.com%2FTheTechLabs" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeedproxy.google.com%2FTheTechLabs" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feedproxy.google.com/TheTechLabs" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeedproxy.google.com%2FTheTechLabs" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeedproxy.google.com%2FTheTechLabs" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeedproxy.google.com%2FTheTechLabs" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><item>
		<title>Simulating PicLens with Flex and Away3D – Part 3</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs/~3/7_m_KGon7n0/</link>
		<comments>http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 22:57:17 +0000</pubDate>
		<dc:creator>webmaster@thetechlabs.com (The Tech Labs)</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[XML]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[adobe flex]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[caurina]]></category>

		<category><![CDATA[loading images]]></category>

		<category><![CDATA[oop]]></category>

		<category><![CDATA[photo viewer]]></category>

		<category><![CDATA[PicLens]]></category>

		<category><![CDATA[planes]]></category>

		<category><![CDATA[scene]]></category>

		<category><![CDATA[skinning]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[tweener]]></category>

		<category><![CDATA[web-design]]></category>

		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=121</guid>
		<description><![CDATA[<p>Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 3, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Alejandro Santander <a href="http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[
<p><a href="http://feedads.googleadservices.com/~a/jCHu-TO-_m8z0Ia3RRfklpn4lgA/a"><img src="http://feedads.googleadservices.com/~a/jCHu-TO-_m8z0Ia3RRfklpn4lgA/i" border="0" ismap="true"></img></a></p><p>Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 3, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. You will make <a title="See the final Application" href="http://thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Finished/"  target="_blank">this</a>.</p>
<p><strong>Requirements:</strong></p>
<ul>
<li><a title="Try / Buy Adobe Flash CS3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Adobe Flash CS3</a></li>
<li><a title="Try / Buy Adobe Flex Builder 3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Adobe Flex Builder 3</a></li>
<li><a title="Download Away3D Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" target="_blank">Away3d Library</a> (I recommend using the version I used)</li>
<li><a title="Download Tweener Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" target="_blank">Tweener Library</a></li>
<li><a title="Download Source Files" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Finished.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Finished.zip');" target="_blank">Source Files</a></li>
</ul>
<p><strong>Pre Requisites:</strong></p>
<ul>
<li>Having done Part 1 and 2 of this tutorial.</li>
<li>Intermediate programming skills.</li>
<li>Moderate knowledge of AS3.</li>
<li>Basic Familiarity with OOP.</li>
<li>Basic knowledge of Flash CS3.</li>
</ul>
<p style="text-align: center;"><img class="aligncenter" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0011.jpg" alt="Pic Lens" width="541" height="196" /></p>
<h3>Step 0:</h3>
<p>This is the last section of the tutorial we’ve been working on. We’re going to wrap up everything we’ve done so far and make our work a solid, working application, which we can use and even extend in the future. First, we will centralize all arbitrary parameters into what’s known as a model, then, we’re going to connect the photo gallery into an external xml so we can load images dynamically, and finally we’re going to enhance our graphics a little bit by adding a reflection effect to the 3D scene.</p>
<h3>Step 1 – Centralizing data:</h3>
<p>As I stated before, we will start by creating a place holder for all arbitrary variables used so far. With arbitrary variables I mean values that we’ve chosen such as the camera’s tween time in the “moveTo()” method within CameraController, or the Z position of the cameraTarget that can greatly affect the nature of the camera’s motion. All these will be placed in a class that will hold these static constants and will also be used to hold dynamic variables further on, so they can be accessed easily from anywhere in the application. So, go ahead and create a new folder next to “view” called “model”. In it, create a new Actionscript Class called “Model.as”.</p>
<p>Now, I need you to work alone for a while. The job to do is recognise all the values you have used so far throughout the application, that you think would be a good idea to name into a variable and control from this central class. Then, all these variables will be declared in Model.as as static constants. This is how my class looks after doing just that:</p>
<pre>package  com.li.photoviewer.model

{ 

     public class Model

     {

          public static const  CAMERA_Z:Number = -2000;

          public static const  CAMERA_Z_ZOOMED:Number = -1500;

          public static const  CAMERA_ZOOM_TIME:Number = 1;

          public static const  CAMERA_ZOOM_EASE:String = "easeoutexpo";

          public static const  CAMERATARGET_FRICTION:Number = 0.95;

          public static const  CAMERATARGET_BOUNCE_FACTOR:Number = 0.5;

          public static const  CAMERATARGET_DRAG_FACTOR:Number = 0.1;

          public static const CAMERATARGET_SPEED_FACTOR:Number  = 0.05;

          public static const  CAMERATARGET_Z:Number = -100;

          public static const  CAMERATARGET_MOVETO_TIME:Number = 1;

          public static const  CAMERATARGET_MOVETO_EASE:String = "easeoutexpo";

          public static const  PHOTO_PLANE_SEGMENTS:Number = 3;

          public static const  PHOTO_MATERIAL_SMOOTH:Boolean = true;

          public static const  PHOTO_FADEIN_TIME:Number = 0.25;

          public static const  PHOTO_SPACING:Number = 750;

          public static const  BG_COLOR1:uint = 0x222222;

          public static const  BG_COLOR2:uint = 0x000000;

          public static const  BG_COLOR_RATIO:uint = 80

          public function Model()

          {

          }

     }

}</pre>
<p>“public  static const” is a way to declare a variable that will be accessible from the  outside of the class, can be accessed without instantiating the holder class,  and will not change. If you don’t what Im talking about, you should see how we  are going to use these variables and then come back to what I’ve just said and  you should get it right away.</p>
<h3>Step 2 – Connecting to the centralized  data:</h3>
<p>So far all  this is completely useless unless we connect our classes to Model.as, so that  the constants can be used. This is done very easily; for instance to connect  the “0.05” value representing a camera velocity factor, we do as in the  following code:</p>
<pre>private function followTarget(evt:Event):void

{

     camera.lookAt(cameraTarget.position);

     var dX:Number = cameraTarget.x - camera.x;

     camera.x  += dX*0.05;

...</pre>
<p>Simply change  to:</p>
<pre>private function followTarget(evt:Event):void

{

     camera.lookAt(cameraTarget.position);

     var dX:Number = cameraTarget.x - camera.x;

     camera.x  += dX*Model.CAMERATARGET_SPEED_FACTOR;

     ...</pre>
<p>As long as the  model has been imported in CameraController of course:</p>
<pre>import com.li.photoviewer.model.Model;</pre>
<p>So this is  what you should do next. Import Model.as in all the view and controller  classes, and connect the values to it. If you’ve imported the model into a  class first, you should get useful codehints from Flex to help you complete  this task. When you’re done, you’ll have the power to very precisely tweak the entire  application from Model.as. You should play around with this to tune it to your  liking.</p>
<h3>Step 3 – Setting up an external XML:</h3>
<p>Now that  our model is set up and working, we will read data from an external xml, and  also use the model to store the data contained in the xml. We will trigger a  service that will read an xml and detail the images that will be loaded in our  application, and once this service is done, the 3D scene will build itself  based on this data. For this, lets start by designing our xml. Create a folder  named “data” and in it a new file named “data.xml”. The folder should be next  to “com” or  “away3d” folders. Then  design the xml structure of data.xml like this:</p>
<pre>&lt;?xml  version="1.0"?&gt;

&lt;imgs&gt;

     &lt;img name="testImage.jpg"/&gt;

     &lt;img  name="1.jpg"/&gt;

     &lt;img  name="2.jpg"/&gt;

     &lt;img  name="3.jpg"/&gt;

     &lt;img  name="4.jpg"/&gt;

     &lt;img  name="5.jpg"/&gt;

     &lt;img  name="6.jpg"/&gt;

     &lt;img  name="7.jpg"/&gt;

     &lt;img  name="8.jpg"/&gt;

     &lt;img  name="9.jpg"/&gt;

     &lt;img  name="10.jpg"/&gt;

&lt;/imgs&gt;</pre>
<p>The xml is extremely  simple, it just contains the name of each image.</p>
<h3>Step 4 – Creating an XML Reader:</h3>
<p>We should  continue by creating a folder called “services” next to “view” and in it a new  Actionscript Class called “XmlReader”, which will take care of extracting the  data from the xml. This class should have two variables in its constructor,  “xmlPath” as a string and “onComplete” as a function, It will also have a  “loader” variable as a URLoader:</p>
<pre>private var xmlPath:String;

private var onComplete:Function;

private var loader:URLLoader;

public function XmlReader(xmlPath:String,  onComplete:Function)

{

     this.xmlPath = xmlPath;

     this.onComplete = onComplete;

     loader = new URLLoader();

     loader.addEventListener(Event.COMPLETE,  completeHandler);

     loader.load(new URLRequest(xmlPath));

}</pre>
<p>The path of  the xml file is stored, (as well as “onComplete” which we will see in a  minute), then the loader is initialized and triggered. The function  “completeHandler()” will, as its name says, handle the loader once it’s done:</p>
<pre>private function completeHandler(evt:Event):void

{

     var xmlDocument:XMLDocument = new  XMLDocument();

     xmlDocument.ignoreWhite  = true;

     var xml:XML = new XML(evt.target.data);

     xmlDocument.parseXML(xml.toString());

     for(var i:uint; i&lt;xmlDocument.firstChild.childNodes.length;  i++)

          Model.data.push(xmlDocument.firstChild.childNodes[i].attributes.name);

     onComplete();

}</pre>
<p>The handler  parses all the data in the xml and injects it in the model. Of course, we need  to go back to Model.as and declare this “data” variable that we are referring  to. Just add it after all the constants:</p>
<pre>public static var data:Array = [];</pre>
<p>Finally  (referring again to the completeHandler method), “onComplete()” gets called as  soon as all the parsing is done. Remember that we designed this XmlReader to  receive a reference to this external function when it is instantiated. This  will simply be the function to be called when the reader has finished its job.</p>
<h3>Step 5 – Using the reader:</h3>
<p>Lets  implement this now in the application’s main class, PhotoViewer3D.as. Carefully  study these modifications:</p>
<pre>package

{

     import com.li.photoviewer.services.XmlReader;

     import com.li.photoviewer.view.PhotoScene;

     import flash.display.Sprite;

     import flash.display.StageAlign;

     import flash.display.StageScaleMode;

     [SWF(backgroundColor="0x000000", frameRate="30")]

     public class PhotoViewer3D extends Sprite

     {

          public function PhotoViewer3D()

          {

               stage.scaleMode  = StageScaleMode.NO_SCALE;

               stage.align  = StageAlign.TOP_LEFT;

               var reader:XmlReader = new XmlReader(&#8221;data/data.xml&#8221;, init);

          }

          private function init():void

          {

               var photoScene:PhotoScene = new PhotoScene();

               addChild(photoScene);

          }

     }

}</pre>
<p>I’ve just  instantiated an XmlReader, pointed it to the xml path, put the creation of the  scene in its own separate method, and also pointed the reader to this method so  its called as soon as its done.</p>
<h3>Step 6 – Loading the images:</h3>
<p>The next  step is pretty obvious. We now have the data array containing all the names of  our images, waiting for us in the model and we’ve also delayed the creation of  the 3D scene till after this data has been obtained. So we just need to alter  the “initObjects()” method of PhotoScene.as to read this data. It’s too simple  actually:</p>
<pre>private function initObjects():void

{

     for(var i:uint; i&lt;Model.data.length; i++)

     {

          var photo:PhotoLoader = new PhotoLoader("imgs/" + Model.data[i]);

          photo.x  = i*Model.PHOTO_SPACING;

          scene.addChild(photo);

          cameraController.maxX  = photo.x;

          photo.addOnMouseDown(photoClickHandler);

     }

}</pre>
<p>That’s it.  Test the application and see how it now loads all the corresponding different  images. We’re practically done now, I just want to add an additional effect to  the app…</p>
<h3>Step 7 – Adding a reflection:</h3>
<p>As it is  usual in many open source projects, many people share their code in classes  that can be very handy and easy to use. You can very often download a class  that does a particular thing, use it, and never know how it actually works. So  that’s what we’ll do, we will greatly enhance the look of our application by  downloading a class, and I will make my point of showing how great it is to use  other people’s classes, or even design classes yourself to be reusable in this  way.</p>
<p><a title="Download Reflection.as" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/reflection.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/reflection.zip');" target="_self">Download Reflection.as</a> and paste it  in the view folder.</p>
<p>The class  should be ready to work, except that its package path is all wrong. This is  pretty logical, since I’ve just used it for another project and it was placed  completely on a different place. Correct this path to the class’ current  location. You can also look into the class, now or later, to understand how it  works and maybe learn new things that could motivate you to other uses or even  new ideas with Away3D.</p>
<h3>Step 8 – Plugging in the reflection:</h3>
<p>Go back to  PhotoScene.as and declare the reflection instance (we don’t need to import  Reflection.as since it is in the same package as PhotoScene.as):</p>
<pre>private var  reflection:Reflection;</pre>
<p>Then, in the “initScene()” method, initialize  it and add it to the display list:</p>
<pre>reflection = new Reflection(scene, camera);
addChild(reflection);</pre>
<p>And  finally, in “renderScene()” add a call to the reflections rendering method:</p>
<pre>private function renderScene(evt:Event):void

{

reflection.render();

view.render();

}</pre>
<p>I also took  the time to connect the Reflection class to the model and drop its arbitrary  variables there. I even set up a USE_REFLECTION constant in the model and  applied this Boolean value in the initialization of the reflection in  “initScene()” and the “renderScene()” method too. All this allows you to, not  only tweak the app to look good, but also to consider performance issues. With  the values that you should have in the model after you do this, you can really  optimize the application.</p>
<pre>public static const USE_REFLECTION:Boolean = false;

public static const REFLECTION_OFFSET:Number = -525;

public static const REFLECTION_BLUR:Number = 8;

public static const REFLECTION_ALPHA:Number = 0.25;

public static const REFLECTION_SCALING:Number = 2;</pre>
<p>So, that’s  it! The application is flexible enough to be extended easily. Maybe a  horizontal scroller could be a good idea, for example… I leave that to your  creativity. I wanted to keep the MVC architecture as simple as I could by  avoiding custom events, singleton classes, etc, but those could be good things  to investigate for future projects. On the other hand, I really recommend  playing with the Away3D engine, the possibilities with it are endless!!</p>
<p>I hope  you’ve enjoyed the tutorial. I’m looking forward to make another one when I can  =)</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%203&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Fxml%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-3%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%203&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Fxml%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-3%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs/~4/7_m_KGon7n0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/feed/</wfw:commentRss>
		<media:content url="http://feedproxy.google.com/~r/TheTechLabs/~5/yx0IqDxR6bo/away3d.zip" fileSize="749362" type="application/zip" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 3, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. posted in 3D by Alejandro Santande</itunes:subtitle><itunes:author>The Tech Labs</itunes:author><itunes:summary> Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 3, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. posted in 3D by Alejandro Santander Leave A Comment &amp;copy;2008 The Tech Labs. All Rights Reserved.</itunes:summary><itunes:keywords>Tutorials,adobe,air,flash,flex,webdesign</itunes:keywords><feedburner:origLink>http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/TheTechLabs/~5/yx0IqDxR6bo/away3d.zip" length="749362" type="application/zip" /><feedburner:origEnclosureLink>http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip</feedburner:origEnclosureLink></item>
		<item>
		<title>Simulating PicLens with Flex and Away3D – Part 2</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs/~3/eDMVM1zmskY/</link>
		<comments>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 21:27:21 +0000</pubDate>
		<dc:creator>webmaster@thetechlabs.com (The Tech Labs)</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[adobe flex]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[caurina]]></category>

		<category><![CDATA[loading images]]></category>

		<category><![CDATA[oop]]></category>

		<category><![CDATA[photo viewer]]></category>

		<category><![CDATA[PicLens]]></category>

		<category><![CDATA[planes]]></category>

		<category><![CDATA[scene]]></category>

		<category><![CDATA[skinning]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[tweener]]></category>

		<category><![CDATA[web-design]]></category>

		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=120</guid>
		<description><![CDATA[<p>Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 2, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Alejandro Santander <a href="http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[
<p><a href="http://feedads.googleadservices.com/~a/5F_XoQW-uTqi3HARov-D6UsNiPM/a"><img src="http://feedads.googleadservices.com/~a/5F_XoQW-uTqi3HARov-D6UsNiPM/i" border="0" ismap="true"></img></a></p><p><span lang="EN-GB">Step by  step guide for creating a PicLens type 3D photo viewer with Flex and Away3d.  This is step 2, of a 3 part tutorial that will sweep many useful techniques  used in web application design, Flex, and Flash 3D design. </span></p>
<p>In the final the result will be <a title="See the Final Application Demo" href="http://thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Finished/"  target="_blank">this</a>.</p>
<p><strong>Requirements:</strong></p>
<ul>
<li><a title="Try / Buy Adobe Flash CS3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Adobe Flash CS3</a></li>
<li><a title="Try / Buy Adobe Flex Builder 3" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Adobe Flex Builder 3</a></li>
<li><a title="Download Away3D Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" target="_blank">Away3d Library</a> (I recommend using the version I used)</li>
<li><a title="Download Tweener Library" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" target="_blank">Tweener Library</a></li>
<li><a title="Download Source Files" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip');" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part2.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part2.zip');" target="_blank">Source Files</a></li>
</ul>
<p><span lang="EN-GB"> </span><strong><span lang="EN-GB">Pre Requisites:</span></strong></p>
<p><!--[if !supportLists]--></p>
<ul>
<li> <span lang="EN-GB">Having  done Part 1 of this tutorial</span></li>
<li> <span lang="EN-GB">Intermediate  programming skills</span></li>
<li> <span lang="EN-GB">Moderate  knowledge of AS3</span></li>
<li> <span lang="EN-GB">Basic  Familiarity with OOP</span></li>
<li><span lang="EN-GB">Basic  knowledge of Flash CS3</span></li>
</ul>
<p><strong><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0011.jpg" alt="" /></strong></p>
<h3><strong><span lang="EN-GB">Step</span></strong><strong><span lang="EN-GB"> 0</span></strong></h3>
<p><span lang="EN-GB">In this  part we’re going to use the PhotoLoader component we designed previously, and  set up the 3D scene showing multiple instances of it. Then, we’re going to  develop the interactivity of the user for that scene. This will be the most  intense part of the series, but hopefully the most fun.</span></p>
<h3><strong><span lang="EN-GB">Step 1 – Adapting the TestScene to the  official scene</span></strong></h3>
<p><span lang="EN-GB">So, the  first thing we have to do is rename our TestScene.as. Right click on the file,  choose Rename and select PhotoScene as the new name. Flex should have updated  the references to this class in your source, so that no errors are shown.  However, you should go to the main file, “PhotoViewer3D” and rename the  PhotoScene instance to “scene”, its not necessary, but its tidy. If any errors  are thrown, it’s a good time to get to know the Flex Console. It is a panel at  the bottom of Flex, in which errors are detected before compilation time. Its  very probable that you noticed it already, just making sure. If you double  click on one of the errors it shows you, Flex takes you directly to the source  of that error. I really don’t know any quicker way to debug errors in  Actionscript projects.</span></p>
<p><span lang="EN-GB"> </span></p>
<h3><strong><span lang="EN-GB">Step 2 – Multiple objects</span></strong></h3>
<p><span lang="EN-GB">Now, we’re  going to modify the “initObjects()” method in PhotoScene to create 10 instances  of PhotoLoader instead of just one, and arrange these instances horizontally.  Use this code:</span></p>
<pre><strong>private</strong> <strong>function</strong> initObjects():<strong>void</strong>
{
     <strong>for</strong>(<strong>var</strong> i:uint; i&lt;10; i++)
     {
          <strong>var</strong> photo:PhotoLoader = <strong>new</strong> PhotoLoader(<strong>&#8220;imgs/testImage.jpg&#8221;</strong>);
          photo.x  = i*700; &lt;
          scene.addChild(photo);
     }
}</pre>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0031.jpg" alt="" /></p>
<p><span>You should  now see more instances to the right of the first one, even though we cant see  all of them due to our limited camera control lines in the “renderScene()”  method.</span></p>
<h3><strong><span lang="EN-GB">Step 3 – Enhancing camera controls</span></strong></h3>
<p><span lang="EN-GB">That’s what  we’re going to do now; begin building a controller class that will provide more  advanced camera user control. This part is pretty fun, since we’ve reached the  level of complexity in which Away3D starts showing off its awesome  capabilities.</span></p>
<p><span lang="EN-GB">Delete  these lines in the “renderScene()” method in PhotoScene, we wont need them  anymore:</span></p>
<pre>camera.x = 3*(mouseX - stage.stageWidth/2);
camera.y = 3*(mouseY - stage.stageHeight/2);
camera.lookAt(<strong>new</strong> Number3D(0, 0, 0));</pre>
<p><span lang="EN-GB">The new  code that we will develop to achieve the enhanced camera motion will be more  complex, logically, so it will not reside in our PhotoScene class. It will be  in its own class, designed specifically for this, that is, camera motion  control. Create a new folder next to “view” and name it “controller”. In it,  create a new Actionscript Class named “CameraController”. Once done, make this  class extend Sprite.</span></p>
<p><span lang="EN-GB">Now, back  in PhotoScene.as, create a new variable named cameraController as:</span></p>
<pre><strong>private</strong> <strong>var </strong>cameraController:CameraController;<strong><span lang="EN-GB"> </span></strong></pre>
<p><span lang="EN-GB">After the  “initScene()” call in the “init()” method in PhotoScene, place a new call to  “initCameraController()”. And lets define this as follows:</span></p>
<pre><strong>private</strong> <strong>function</strong> initCameraController():<strong>void</strong>
{
    <strong>var</strong> cube:Cube = <strong>new</strong> Cube();
    cube.width  = cube.height = cube.depth = 10; 

     cube.z =  -100; 

     scene.addChild(cube); 

     cameraController  = <strong>new</strong> CameraController(camera, cube); 

     addChild(cameraController);</pre>
<p><span lang="EN-GB">Don’t  worry, I’ll explain. What we did is create a small cube and added it to the scene.  Then, we instantiated our new CameraController, passing it two parameters and  added it to the display. Why those two parameters? And what is the purpose of  that cube?! As you will fully understand later, the cube will be used as the  camera’s target, the camera will constantly be “looking” at it and trying to  follow it. This is a very interesting technique used in 3D, since it provides a  way to simulate natural and realistic camera motion effects.</span></p>
<p><strong><span lang="EN-GB"> </span></strong></p>
<h3><strong><span lang="EN-GB">Step 4 – Building the CameraController</span></strong></h3>
<p><span lang="EN-GB">Great, now lets  go back to the controller and shape it up a little. In PhotoScene, when we  instantiated it, we passed it 2 parameters. Lets assimilate them in the  constructor and store these references. We’re also going to create an init  method that will be called once the instance has been added to the stage, as  we’ve done before:</span></p>
<pre><strong>private</strong> <strong>var</strong> camera:Camera3D; 

<strong>private</strong> <strong>var</strong> cameraTarget:Cube; 

<strong>public</strong> <strong>function</strong> CameraController(camera:Camera3D,  cameraTarget:Cube) 

{ 

     <strong>this</strong>.camera = camera; 

     <strong>this</strong>.cameraTarget = cameraTarget; 

     <strong>this</strong>.addEventListener(Event.ADDED_TO_STAGE, init, <strong>false</strong>, 0, <strong>true</strong>); 

} 

<strong>private</strong> <strong>function</strong> init(evt:Event):<strong>void</strong> 

{ 

     <strong>this</strong>.removeEventListener(Event.ADDED_TO_STAGE, init); 

}</pre>
<p><span lang="EN-GB">Add a new  event listener in the “init()” method to call a new “followTarget()” in  enterframe.</span></p>
<pre><strong>this</strong>.addEventListener(Event.ENTER_FRAME,  followTarget);</pre>
<p><span lang="EN-GB">And define  “followTarget()” as:</span></p>
<pre><strong>private</strong> <strong>function</strong> followTarget(evt:Event):<strong>void</strong> 

{ 

     cameraTarget.x  += 10; 

     camera.lookAt(cameraTarget.position); 

}</pre>
<p><span lang="EN-GB">Test it  out. You should be able to see the little cube starting next to the first photo  and then moving to the right. The camera will look at it as it goes away. Lets  extend it a bit further by telling the camera not just to look at it, but also to  try to keep up with it. Add these lines to the “followTarget()” method:</span></p>
<pre>var  dX:Number = cameraTarget.x - camera.x;

camera.x += dX*0.05;</pre>
<p><span>Test it  again… Im sure you can tell the different and understand the code with what  you see.</span></p>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image0051.jpg" alt="" /></p>
<p><span lang="EN-GB">Before we  go on, delete the first line in “followTarget()” that moves the camera target  to the right, it was just used for demonstration purposes. From now on, the  target wont move by its own, we are going to move it.</span></p>
<h3><strong><span lang="EN-GB">Step 5 – Setting up interactivity</span></strong></h3>
<p><span lang="EN-GB">That looks  good, but now lets make it more realistic, and most importantly, interactive.  In PhotoScene, we are going to modify the “initObjects()” method again to  register a click listener on the photos, and that method is going to call  another method in the camera controller, telling it to move the camera to that  photo. Don’t worry, you’ll be amazed by how simple this is going to be.</span></p>
<p><span lang="EN-GB">In the for  loop inside of “initObjects()” in PhotoScene, add this line at the end:</span></p>
<pre>photo.addOnMouseDown(photoClickHandler);</pre>
<p><span lang="EN-GB">And add a  couple of lines in the constructor of PhotoLoader to tell the cursor to show a  hand when we roll over the photos:</span></p>
<pre><strong>this</strong>.ownCanvas = <strong>true</strong>; 

<strong>this</strong>.useHandCursor = <strong>true</strong>;<strong><span lang="EN-GB"> </span></strong></pre>
<p><span lang="EN-GB">Then,  define the “photoClickHandler()” back in PhotoScene method as:</span></p>
<pre><strong>private</strong> <strong>function</strong> photoClickHandler(evt:MouseEvent3D):<strong>void</strong> 

{ 

     cameraController.moveTo(evt.object.x); 

}</pre>
<p><span lang="EN-GB">Yes, we  need to define the public “moveTo()” method in the CameraController, so lets do  it:</span></p>
<pre><strong>public</strong> <strong>function</strong> moveTo(X:Number):<strong>void</strong> 

{ 

Tweener.addTween(cameraTarget, {x:X,  time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>}); 

}</pre>
<p><span lang="EN-GB">It will  work as long as you import the Tweener class in CameraController. Test the  application and click on the images. That’s it!!</span></p>
<h3><strong><span lang="EN-GB">Step 6 – Setting up mouse drag</span></strong></h3>
<p><span lang="EN-GB">Next, the  app is going to have a pretty cool feature, which is the ability of the user to  click on the canvas and drag himself (the camera that is) around the scene.  We’ll manage this in 3 steps, so follow along.</span></p>
<p><span lang="EN-GB">First,  we’re going to need 2 clips that will capture the mouse down and mouse up for  the dragging. One will be behind the photos, and the other above them. Besides,  we will take advantage of the one behind to make the app look a bit better by  using it as a background as well. Modify “initScene()” in PhotoScene like this:</span></p>
<pre><strong>private</strong> <strong>function</strong> initScene():<strong>void</strong> 

{ 

     scene = <strong>new</strong> Scene3D(); 

     camera = <strong>new</strong> Camera3D(); 

     camera.zoom  = 10; 

     camera.focus  = 200; 

     camera.z =  -2000; 

     background  = <strong>new</strong> Sprite(); 

     <strong>var</strong> mat:Matrix = <strong>new</strong> Matrix(); 

     mat.rotate(-Math.PI/2); 

     background.graphics.beginGradientFill(GradientType.LINEAR,  [0x222222, 0x000000], [1, 1], [0, 80], mat); 

     background.graphics.drawRect(0,  0, stage.stageWidth, stage.stageHeight); 

     background.graphics.endFill(); 

     addChild(background); 

     background.addEventListener(MouseEvent.MOUSE_DOWN,  handleBackgroundMouseDown); 

     view = <strong>new</strong> View3D(); 

     view.camera  = camera; 

     view.scene  = scene; 

     view.x =  stage.stageWidth/2; 

     view.y =  stage.stageHeight/2; 

     view.clip  = <strong>new</strong> RectangleClipping(-stage.stageWidth/2,  -stage.stageHeight/2, stage.stageWidth/2, stage.stageHeight/2); 

     addChild(view); 

     foreground  = <strong>new</strong> Sprite(); 

     foreground.graphics.beginFill(0&#215;00FF00,  0.5); 

     foreground.graphics.drawRect(0,  0, stage.stageWidth, stage.stageHeight); 

     foreground.graphics.endFill(); 

     foreground.visible  = <strong>false</strong>; 

     addChild(foreground); 

     foreground.addEventListener(MouseEvent.MOUSE_UP,  handleForegroundMouseUp); 

     foreground.addEventListener(MouseEvent.MOUSE_OUT,  handleForegroundMouseUp); 

}</pre>
<p><span lang="EN-GB">And don’t  forget to declare background and foreground private variables at the beginning  of the class, plus import the GradientType class:</span></p>
<pre><strong>import</strong> flash.display.GradientType;<strong><span lang="EN-GB"> </span></strong></pre>
<p><span lang="EN-GB">What we  just did was add these two before and after the view. It was done in this order  to maintain the layering we talked about before. The background is simply a  sprite with a gradient, and the foreground is a semi transparent green clip  above everything. Comment the 3 listener lines we’ve just added, and “</span><em>foreground.visible = false</em><span lang="EN-GB">” and test the app. As you can see,  the sprites have been added to the display.</span></p>
<p><span lang="EN-GB">Now,  uncomment those lines and go ahead and define the handler methods as:</span></p>
<pre><strong>private</strong> <strong>function</strong> handleBackgroundMouseDown(evt:MouseEvent):<strong>void</strong> 

{ 

     foreground.visible  = <strong>true</strong>; 

} 

<strong>private</strong> <strong>function</strong> handleForegroundMouseUp(evt:MouseEvent):<strong>void</strong> 

{ 

     foreground.visible  = <strong>false</strong>; 

}</pre>
<p><span lang="EN-GB">If you test  the app again, you’ll see the idea behind all this. The background captures the  mouse down and shows the foreground, which is simply there to capture the mouse  up. Even though this might look confusing, its pretty practical. If it wasn’t  there and we had set up the background to capture the mouse up, it wouldn’t  work very well since we could press on the background and then, while the mouse  is still pressed, move over to a photo and release the mouse once we’re there…  The background wouldn’t have captured the mouse up, because the photo would  have captured it. So, what we’ve just done makes sure we don’t have to worry  about this kind of stuff. It’s solid, Im sure there might be other methods, but  Im comfortable with this one. Before we continue, set the foreground’s draw  alpha from 0.5 to 0 so we don’t see it anymore (it will do its job anyway).</span></p>
<p><strong><span lang="EN-GB"> </span></strong></p>
<h3><strong><span lang="EN-GB">Step 7 – Designing the mouse drag</span></strong></h3>
<p><span lang="EN-GB">We need to  define the dragging now. On the handlers we’ve just created, add “</span>cameraController.startCameraDrag();<span lang="EN-GB">” for the mouse down handler, and “</span>cameraController.stopCameraDrag();<span lang="EN-GB">” for the mouse up handler. And of  course, we need to define those methods in the CameraController class. These  two methods will simply toggle a mouse move event listener that will  continuously call a dragCamera method while the mouse is pressed:</span></p>
<pre><strong>public</strong> <strong>function</strong> startCameraDrag():<strong>void</strong> 

{ 

lastMouseX = stage.mouseX; 

     stage.addEventListener(MouseEvent.MOUSE_MOVE,  dragCamera, <strong>false</strong>, 0 , <strong>true</strong>); 

} 

<strong>public</strong> <strong>function</strong> stopCameraDrag():<strong>void</strong> 

{ 

     stage.removeEventListener(MouseEvent.MOUSE_MOVE,  dragCamera); 

} 

<strong>private</strong> <strong>function</strong> dragCamera(evt:MouseEvent):<strong>void</strong> 

{ 

     <strong>var</strong> dX:Number = <span style="text-decoration: underline;">lastMouseX</span> - stage.mouseX; 

     cameraTargetVX  += dX*0.1; 

     lastMouseX  = stage.mouseX; 

}</pre>
<p><span lang="EN-GB">Of course,  you’re going to need to define “lastMouseX” and “cameraTargetVX” as private  variables at the top of the class. Make sure you set cameraTargetVX to zero  when you declare it. Ill explain what’s going on shortly, I want you to see it  working first…</span></p>
<p><span lang="EN-GB">To apply  what we’ve just done, add these lines to the “followTarget()” method:</span></p>
<pre>cameraTarget.x += <span style="text-decoration: underline;">cameraTargetVX</span>; 

cameraTargetVX *= 0.95;</pre>
<p><span lang="EN-GB">And to  correct incongruencies, add “</span>cameraTargetVX  = 0;<span lang="EN-GB">” in the “moveTo()”  method.</span></p>
<p><span lang="EN-GB">Check it  out by testing the app and clicking and dragging from the background. Its simple  code, with pretty impressive smooth results. So, as I said, let me explain a  little now. When a drag is started, the controller stores the current mouse  position and begins the continuous call to the drag method. In this method, the  first thing that happens is that the stored initial mouse position is compared  to the actual mouse position every time the mouse moves. This value is then  used to alter “cameratargetVX” which is just a variable that represents the  velocity of the camera, and the current mouse position is again stored. On the  mean time, in the “followTarget()” method, the velocity variable is constantly  being added to the cameraTarget’s position. This is the very basics of  simulating velocity physics on programming. In this method, the velocity value  is also dampened by 5% to simulate friction. Finally, the “stopCameraDrag()”  method unplugs the continuous call to “dragCamera()”.</span></p>
<h3><strong><span lang="EN-GB">Step 8 – Adding zoom</span></strong></h3>
<p><span lang="EN-GB">Next, we  will add a cool zoom effect, which is going to be really simple. Add this  methods in Camera Controller:</span></p>
<pre><strong>private</strong> <strong>function</strong> zoomIn():<strong>void</strong> 

{ 

     Tweener.addTween(camera,  {z:-1500, time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>}); 

} 

<strong>private</strong> <strong>function</strong> zoomOut():<strong>void</strong> 

{ 

     Tweener.addTween(camera,  {z:-2000, time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>}); 

}</pre>
<p><span lang="EN-GB">And add a  zoomIn() call in the “moveTo()” method, and a zoomOut() call in the  “startCameraDrag()” method. Test the app. It’s as simple as that, we now have a  little zoom effect working.</span></p>
<p><strong><span lang="EN-GB"> </span></strong></p>
<h3><strong><span lang="EN-GB">Step 9 – Containing motion</span></strong></h3>
<p><span lang="EN-GB">Before we  finish this part of the tutorial, we need to face a little issue you might have  noticed: The user can drag himself far away from the photos, and we don’t want  this. We want to contain the camera in an area where the user will always see  the photos.</span></p>
<p><span lang="EN-GB">To define  the area that the user will move in, define two public variables in  CameraController. They’re public because, even though we define them in  CameraController, they will be filled up from the PhotoScene each time a new  photo is created:</span></p>
<pre><strong>public</strong> <strong>var</strong> minX:Number = 0; 

<strong>public</strong> <strong>var</strong> maxX:Number =  0;</pre>
<p><span lang="EN-GB">Now go to  PhotoScene and, in “initObjects()” add “</span>cameraController.maxX = photo.x;<span lang="EN-GB">” inside the end of for loop. This results in  that each time a photo is created, the scene reports the camera controller how  far the camera target should be able to move.</span></p>
<p><span lang="EN-GB">Now last,  but not least, add this containment code to the end of “followTarget()” in  cameraController:</span></p>
<pre><strong>if</strong>(cameraTarget.x  &gt; maxX) 

{ 

     cameraTarget.x  = maxX; 

     cameraTargetVX  *= -0.5; 

} 

<strong>else</strong> <strong>if</strong>(cameraTarget.x &lt; minX) 

{ 

     cameraTarget.x  = minX; 

     cameraTargetVX  *= -0.5; 

}</pre>
<p><span lang="EN-GB">This simply  checks if the target has exceeded the limits of the scene, and if so, docks the  target at one of the limits and inverts its velocity to make it “bounce”. You  may enhance this code by making it consider positions before a velocity value  is applied, etc. It would look better, but I wanted to keep things as simple as  possible here.</span></p>
<p><span lang="EN-GB">And that  does it for part 2 of the tutorial… To wrap things up go to PhotoScene and add  “cube.visible = false;” in “initCameraController()” so that the little cube is  hidden from the user.</span></p>
<h3><strong><span lang="EN-GB">Next</span></strong></h3>
<p><span lang="EN-GB">On part 3  we will give the application a closure by centralizing arbitrary variables,  enhancing graphics a bit, and connecting it to an external XML that will  indicate it what images to load.</span></p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%202&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-2%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%202&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-2%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs/~4/eDMVM1zmskY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/feed/</wfw:commentRss>
		<media:content url="http://feedproxy.google.com/~r/TheTechLabs/~5/yx0IqDxR6bo/away3d.zip" fileSize="749362" type="application/zip" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 2, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. posted in 3D by Alejandro Santande</itunes:subtitle><itunes:author>The Tech Labs</itunes:author><itunes:summary> Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 2, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. posted in 3D by Alejandro Santander Leave A Comment &amp;copy;2008 The Tech Labs. All Rights Reserved.</itunes:summary><itunes:keywords>Tutorials,adobe,air,flash,flex,webdesign</itunes:keywords><feedburner:origLink>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/TheTechLabs/~5/yx0IqDxR6bo/away3d.zip" length="749362" type="application/zip" /><feedburner:origEnclosureLink>http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip</feedburner:origEnclosureLink></item>
		<item>
		<title>Simulating PicLens with Flex and Away3D – Part 1</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs/~3/HC3nPEmO0ww/</link>
		<comments>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/#comments</comments>
		<pubDate>Tue, 16 Sep 2008 23:02:11 +0000</pubDate>
		<dc:creator>webmaster@thetechlabs.com (The Tech Labs)</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Effects]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[adobe flex]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[caurina]]></category>

		<category><![CDATA[loading images]]></category>

		<category><![CDATA[oop]]></category>

		<category><![CDATA[photo viewer]]></category>

		<category><![CDATA[PicLens]]></category>

		<category><![CDATA[planes]]></category>

		<category><![CDATA[scene]]></category>

		<category><![CDATA[skinning]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[tweener]]></category>

		<category><![CDATA[web-design]]></category>

		<category><![CDATA[web-development]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=116</guid>
		<description><![CDATA[<p>This tutorial article is a Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 1, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/3d/">3D</a> by Alejandro Santander <a href="http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[
<p><a href="http://feedads.googleadservices.com/~a/KNdDm7Q1ceNP3R3bo8tTasOx-ro/a"><img src="http://feedads.googleadservices.com/~a/KNdDm7Q1ceNP3R3bo8tTasOx-ro/i" border="0" ismap="true"></img></a></p><p>This tutorial article is a Step by  step guide for creating a PicLens type 3D photo viewer with Flex and Away3d.  This is step 1, of a 3 part tutorial that will sweep many useful techniques  used in web application design, Flex, and Flash 3D design.</p>
<p>In the final the result will be <a title="See the Final Application Demo" href="http://thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Finished/"  target="_blank">this</a>.</p>
<h3>Requirements</h3>
<ul>
<li><a title="Try / Buy Adobe Flash CS3" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Adobe Flash CS3</a></li>
<li><a title="Try / Buy Adobe Flex Builder 3" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Adobe Flex Builder 3</a></li>
<li><a title="Download Away3D Library" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip');" target="_blank">Away3d Library</a> (I recommend using the version I used)</li>
<li><a title="Download Tweener Library" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/caurina.zip');" target="_blank">Tweener Library</a></li>
<li><a title="Download Source Files" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Sources/Part1.zip');" target="_blank">Source Files</a></li>
</ul>
<h3>Pre Requisites</h3>
<ul>
<li>Intermediate  programming skills</li>
<li>Moderate  knowledge of AS3</li>
<li>Basic  Familiarity with OOP</li>
<li>Basic  knowledge of Flash CS3</li>
</ul>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image001.jpg" alt="" width="541" height="196" /></p>
<h3>Step 0</h3>
<p>In this  tutorial I will assume that you are familiar with the basics of building an  Actionscript Away3D project in Flex. If you haven’t used these two technologies  together before, it would be best if you go through my <a title="Setting up Away3d with Flex" href="http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/"  target="_self">previous tutorial</a> first. Due to the complexity of this  application, I will need to skip some things to go faster. So, if something is  not explained here, or suddenly a large chunk of code is dropped with no  descriptions, it has been covered (hopefully) in the mentioned tutorial.</p>
<h3>Step 1 – New Project</h3>
<p>Lets get  started. Create a new Actionscript Project in Flex and name it “PhotoViewer3D”.  Then, download the libraries I listed in the requirements and paste them in the  project’s folder.</p>
<p>Now, one of  the things that will be covered here is a very simplified application  architecture that could be a good starting point for any project you do that  implies a moderate level of complexity. For this, all code will be placed in a  folder structure, carefully separating functions between different classes, and  hence emulating the basics of a Model View Controller design pattern. You  should have a general grasp of it by the end of this series.</p>
<p>Right click  on the project’s folder in the Flex Navigator and choose New -&gt; Folder, then  type “com/li/photoviewer/view” and press Finish. Naming folders this way is  known as Reverse Domain Syntax, and is a good programming practice.</p>
<h3>Step 2 – Setting up the scene</h3>
<p>Go to  PhotoViewer3D.as and build a basic main class:</p>
<pre><strong>package</strong>
{
     <strong>import</strong> flash.display.Sprite;
     <strong>import</strong> flash.display.StageAlign;
     <strong>import</strong> flash.display.StageScaleMode;

     <strong>import</strong> com.li.photoviewer.view.TestScene;

[SWF(backgroundColor=<strong>"0x000000"</strong>, frameRate=<strong>"30"</strong>)] 

     <strong>public</strong> <strong>class</strong> <span lang="EN-GB">PhotoViewer3D</span><strong> extends</strong> Sprite
     {
          <strong>public</strong> <strong>function</strong> <span lang="EN-GB">PhotoViewer3D</span>()
          {
               stage.scaleMode  = StageScaleMode.NO_SCALE;
               stage.align  = StageAlign.TOP_LEFT;

               <strong>var</strong> testScene:TestScene = <strong>new</strong> TestScene();
               addChild(testScene);
          }
     }
}</pre>
<p>Line 7  imports an away3D holding class that we haven’t made yet, so we should create it  right away. Right click on the “view” folder and choose New -&gt; Actionscript  Class and name it “TestScene”. It should have the following code in it:</p>
<pre><strong>package</strong> com.li.photoviewer.view 

{ 

     <strong>import</strong> away3d.cameras.Camera3D;
     <strong>import</strong> away3d.containers.Scene3D;
     <strong>import</strong> away3d.containers.View3D;
     <strong>import</strong> away3d.core.clip.RectangleClipping;
     <strong>import</strong> away3d.core.math.Number3D; 

     <strong>import</strong> flash.display.Sprite;
     <strong>import</strong> flash.events.Event; 

     <strong>public</strong> <strong>class</strong> TestScene <strong>extends</strong> Sprite
     {
          <strong>private</strong> <strong>var</strong> scene:Scene3D;
          <strong>private</strong> <strong>var</strong> camera:Camera3D;
          <strong>private</strong> <strong>var</strong> view:View3D; 

          <strong>public</strong> <strong>function</strong> TestScene()
          {
               addEventListener(Event.ADDED_TO_STAGE,  init, <strong>false</strong>, 0, <strong>true</strong>);
          } 

          <strong>public</strong> <strong>function</strong> init(evt:Event):<strong>void</strong>
          {
               removeEventListener(Event.ADDED_TO_STAGE,  init); 

               initScene();
               initObjects();
               addEventListener(Event.ENTER_FRAME,  renderScene);
          } 

          <strong>private</strong> <strong>function</strong> initScene():<strong>void</strong>
          {
               scene  = <strong>new</strong> Scene3D(); 

               camera  = <strong>new</strong> Camera3D();
               camera.zoom  = 10;
               camera.focus  = 200;
               camera.z  = -2000; 

               view  = <strong>new</strong> View3D();
               view.camera  = camera;
               view.scene  = scene;
               view.x  = stage.stageWidth/2;
               view.y  = stage.stageHeight/2;
               view.clip  = <strong>new</strong> RectangleClipping(-stage.stageWidth/2,  -stage.stageHeight/2, stage.stageWidth/2, stage.stageHeight/2);
               addChild(view);
          } 

          <strong>private</strong> <strong>function</strong> initObjects():<strong>void</strong>
          {
               <strong> </strong>
          } 

          <strong>private</strong> <strong>function</strong> renderScene(evt:Event):<strong>void</strong>
          {
               camera.x  = 3*(mouseX - stage.stageWidth/2);
               camera.y  = 3*(mouseY - stage.stageHeight/2);
               camera.lookAt(<strong>new</strong> Number3D(0, 0, 0)); 

               view.render();
          }
     }
}</pre>
<p><strong>NOTE: </strong>If any  of this shocked you, it has all been explained in the tutorial mentioned in Step  0.</p>
<h3>Step 3 – Setting up our PhotoLoader  component</h3>
<p>Create a  new Actionscript Class in the view folder and name it “PhotoLoader”. These will  be our 3D photograph object. The class will extend Away3D’s Plane primitive,  with a few additional features, more particularly, the ability to load an  external image. So, lets start by setting up the plane:</p>
<pre><strong>package</strong> com.li.photoviewer.view
{
<strong>import</strong> away3d.primitives.Plane;

<strong>public</strong> <strong>class</strong> PhotoLoader <strong>extends</strong> Plane
     {
<strong>private</strong> <strong>var</strong> urlPath:String;

          <strong>public</strong> <strong>function</strong> PhotoLoader(urlPath:String)
          { 

               <strong>super</strong>();

               <strong>this</strong>.urlPath = urlPath;

               <strong>this</strong>.rotationX = 90;
               <strong>this</strong>.width = 640;
               <strong>this</strong>.height = 480;
               <strong>this</strong>.segmentsH = 4;
               <strong>this</strong>.segmentsW = 4;
          }
     }
}</pre>
<p>As you can  see, we’ve set up the constructor so that when we instantiate a PhotoLoader  object, we pass it the image name it has to load as a parameter. Now, go back  to TestScene, and in the “iniObjects()” method, make an instance of PhotoLoader  and add it to the scene:</p>
<pre><strong>var</strong> testPhoto:PhotoLoader = <strong>new</strong> PhotoLoader(<strong>&#8220;imgs/testImage.jpg&#8221;</strong>);

scene.addChild(testPhoto);</pre>
<p>The urlPath we passed this time will be irrelevant,  but we’ll pass it anyway so no errors are thrown. Go ahead and test the  application, you should see something like this:</p>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image003.jpg" alt="" width="540" height="400" /></p>
<h3>Step 4 – Skinning the plane with Flash</h3>
<p>First of  all, we need to give the plane a skin or texture. Even though it will contain  an image, it needs to contain something else while it’s loading, and somehow  show progress for that load process. For this, we will design some graphics in  Flash, and bring them to Flex with what I find to be a very practical and  simple technique. We will use a fla file to generate a library.swf file that  will contain some graphics for our application, and then embed that swf in Flex  and extract the clips as we need them. This is a very useful technique, and I  definitely recommend it for any Flex projects that contain design based vector  graphics.</p>
<p>Open Flash,  create a new AS3 Flash File and save it in your project’s folder, next to  PhotoViewer3D.as. Once in it, select File -&gt; Publish Settings and type “assets/library.swf” for the swf output path (deselect  the html output). Now, create a new folder next to that fla called “assets”  either from your file explorer or by right clicking the project’s folder in the  Flex Navigator. Now, if you publish the fla you will see that library.swf shows  up in your newly created assets folder.</p>
<p style="text-align: center;"><img class="aligncenter" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image005.jpg" alt="" width="283" height="312" /></p>
<h3>Step 5 – Creating and extracting the  graphics created in Flash</h3>
<p>Great, now  I wont be describing how to make the graphics in Flash since I believe you must  be very familiar with this. You should <a title="Download the fla file" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip');" target="_self"><strong>download the </strong></a><strong><a title="Download the fla file" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/library.zip');" target="_self">fla</a></strong> and overwrite the one you just made.  Sorry! Just wanted to make sure you understood what’s going on. Now, open the  downloaded fla. You will see a clip called “LoaderFront” made up of a gray box  and a progressBar clip which has in turn a sub clip. The important thing to  notice here is that LoaderFront has a Linkage and its Base Class was changed to  Sprite. Publish it again, go back to Flex, right click on library.swf in the  assets folder and choose Refresh.</p>
<p>This is the  only code you’ll need to pull those graphics from Flex, type it at the top of  the PhotoLoader class (inside Public class…):</p>
<pre>[<strong>Embed</strong>(source=<strong>"assets/library.swf"</strong>, symbol=<strong>"LoaderFront"</strong>)]
<strong>public</strong> <strong>var</strong> LoaderFront:Class;</pre>
<p>You’ve just  extracted the symbol from the swf’s library and assigned it to a LoaderFront  class. If you create a new instance of this class (and add it to the display  tree), you’ll have a graphics object that extends Sprite! And you can treat it  as any other sprite. Great isn’t it?</p>
<h3>Step 6 – Applying the graphics to the  plane</h3>
<p>Go back to  PhotoLoader.as and create these variables for the class:</p>
<pre><strong>private</strong> <strong>var</strong> materialSprite:Sprite;
<strong>private</strong> <strong>var</strong> progressBar:Sprite;
<strong>private</strong> <strong>var</strong> progressBarSubClip:Sprite;</pre>
<p>And then  this method:</p>
<pre><strong>private</strong> <strong>function</strong> initClips():<strong>void</strong>
{
     materialSprite  = <strong>new</strong> LoaderFront();

     progressBar  = Sprite(materialSprite.getChildByName(<strong>&#8220;progressBar&#8221;</strong>));
     progressBarSubClip  = Sprite(progressBar.getChildByName(<strong>&#8220;subClip&#8221;</strong>));
}</pre>
<p>Now we have references to all the clips that we  need. You have to add the “initClips()” call at the end of the constructor  class.</p>
<p>Next, type this new method under the last one  and also make sure you call it from the constructor:</p>
<pre><strong>private</strong> <strong>function</strong> initMaterial():<strong>void</strong>
{
     <strong>var</strong> material:MovieMaterial = <strong>new</strong> MovieMaterial(materialSprite);
     material.smooth  = <strong>true</strong>;

     <strong>this</strong>.<span style="text-decoration: underline;">material</span> = material;
}</pre>
<p>And Test the application. You should now see that the  plane has taken the graphics as its material. Your PhotoLoader class should  look like this so far:</p>
<pre><strong>package</strong> com.li.photoviewer.view
{
     <strong>import</strong> away3d.materials.MovieMaterial;
     <strong>import</strong> away3d.primitives.Plane;
     <strong>import</strong> flash.display.Sprite;
     <strong>public</strong> <strong>class</strong> PhotoLoader <strong>extends</strong> Plane
     {
         [<strong>Embed</strong>(source=<strong>"assets/library.swf"</strong>, symbol=<strong>"LoaderFront"</strong>)]
          <strong>public</strong> <strong>var</strong> LoaderFront:Class;
          <strong>private</strong> <strong>var</strong> urlPath:String;
          <strong>private</strong> <strong>var</strong> materialSprite:Sprite;
          <strong>private</strong> <strong>var</strong> progressBar:Sprite;
          <strong>private</strong> <strong>var</strong> progressBarSubClip:Sprite;
          <strong>public</strong> <strong>function</strong> PhotoLoader(urlPath:String)
          {
               <strong>super</strong>();
               <strong>this</strong>.urlPath = urlPath;
               <strong>this</strong>.rotationX = 90;
               <strong>this</strong>.width = 640;
               <strong>this</strong>.height = 480;
               <strong>this</strong>.segmentsH = 4;
               <strong>this</strong>.segmentsW = 4;
               initClips();
               initMaterial();
          }
          <strong>private</strong> <strong>function</strong> initClips():<strong>void</strong>
          {
               materialSprite  = <strong>new</strong> LoaderFront();
               progressBar  = Sprite(materialSprite.getChildByName(<strong>&#8220;progressBar&#8221;</strong>));
               progressBarSubClip  = Sprite(progressBar.getChildByName(<strong>&#8220;subClip&#8221;</strong>));
          }
          <strong>private</strong> <strong>function</strong> initMaterial():<strong>void</strong>
          {
               <strong>var</strong> material:MovieMaterial = <strong>new</strong> MovieMaterial(materialSprite);
               material.smooth  = <strong>true</strong>;
               <strong>this</strong>.material = material;
          }
     }
}</pre>
<h3>Step 7 – Loading images into the plane</h3>
<p>The final  thing to do for Part 1 of this tutorial, is implement all the image loading  features of our extended plane. For this, we will use a regular Loader instance  and add a few event listeners to check for progress and complete events.</p>
<p>Add the  loader variable next to the other class variables:</p>
<pre><strong>private</strong> <strong>var</strong> loader:Loader;</pre>
<p>And call a new method under the  “initMaterial()” call in the constructor as “initLoader()”, then build the  method:</p>
<pre><strong>private</strong> <strong>function</strong> initLoader():<strong>void</strong>
{
     loader = <strong>new</strong> Loader();
     loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,  progressHandler);
     loader.contentLoaderInfo.addEventListener(Event.INIT,  initHandler);
     materialSprite.addChild(loader);
     loader.alpha  = 0;
}</pre>
<p>The loader is initialized, two listeners are registered,  then the loader is injected to the plane’s material sprite completely  invisible. I’ve made it invisible because I&#8217;m going to make it fade in once the  image has been loaded into it.</p>
<p>Now, lets set up the handlers and a little  “setProgress()” utilitary method:</p>
<pre><strong>private</strong> <strong>function</strong> progressHandler(evt:ProgressEvent):<strong>void</strong>
{
     setProgress(evt.bytesLoaded/evt.bytesTotal);
}
<strong>private</strong> <strong>function</strong> initHandler(evt:Event):<strong>void</strong>
{
     Tweener.addTween(loader,  {alpha:1, time:1, transition:<strong>&#8220;easeoutexpo&#8221;</strong>});
}
<span lang="EN-GB"> </span>
<strong>private</strong> <strong>function</strong> setProgress(value:Number):<strong>void</strong>
{
     progressBarSubClip.scaleX  = value;
}</pre>
<p>Pretty  straight forward. As the image downloads, the progress handler calls the “setProgress()”  function which in turn sets the horizontal scale of the progress bar, and when  the download completes, or more precisely when the loaded content is  initialized, Tweener makes the loader fade in by animating its alpha. Don’t  forget to import Tweener for this:</p>
<pre><strong>import</strong> caurina.transitions.Tweener;</pre>
<h3>Step 8 – Triggering the load</h3>
<p>Next, lets  trigger the load by adding a “loadImage()” method as the last method called in  the constructor and defining it:</p>
<pre><strong>private</strong> <strong>function</strong> loadImage():<strong>void</strong>
{
     loader.unload();
     loader.alpha  = 0;
     setProgress(0);
     loader.load(<strong>new</strong> URLRequest(urlPath));
}</pre>
<p>Finally,  create the imgs folder in the project, download <a title="Download the images" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/imgs.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/imgs.zip');" target="_self">THESE</a> images and paste them in it. Test  the app, you should see the image loaded on the plane:</p>
<p><img src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image007.jpg" alt="" width="540" height="400" /></p>
<p>Watch the Demo <a title="The the Part 1 Demo" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Demos/Part1"  target="_blank">HERE</a>.</p>
<address><strong>NOTE:</strong> </address>
<address>If  you have any security issues at this point you should disable the compilers  network for now. Do this by right clicking the projects folder, choosing  properties, then clicking on the Actionscript Compiler tab and in the  Additional Compiler Settings, type “-use-network=false”. Don’t forget to  disable this when you go online… This is something anyone using Flex gets to  know one way or the other for quickly getting over any sandbox issues.</address>
<p>Next:</p>
<p>On the next  part we will continue to develop our application by using multiple instances of  this PhotoLoader object, developing advanced camera motion and interactivity.</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%201&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-1%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Simulating%20PicLens%20with%20Flex%20and%20Away3D%20%E2%80%93%20Part%201&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsimulating-piclens-with-flex-and-away3d-%25e2%2580%2593-part-1%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs/~4/HC3nPEmO0ww" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/feed/</wfw:commentRss>
		<media:content url="http://feedproxy.google.com/~r/TheTechLabs/~5/yx0IqDxR6bo/away3d.zip" fileSize="749362" type="application/zip" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> This tutorial article is a Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 1, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. posted </itunes:subtitle><itunes:author>The Tech Labs</itunes:author><itunes:summary> This tutorial article is a Step by step guide for creating a PicLens type 3D photo viewer with Flex and Away3d. This is step 1, of a 3 part tutorial that will sweep many useful techniques used in web application design, Flex, and Flash 3D design. posted in 3D by Alejandro Santander Leave A Comment &amp;copy;2008 The Tech Labs. All Rights Reserved.</itunes:summary><itunes:keywords>Tutorials,adobe,air,flash,flex,webdesign</itunes:keywords><feedburner:origLink>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/TheTechLabs/~5/yx0IqDxR6bo/away3d.zip" length="749362" type="application/zip" /><feedburner:origEnclosureLink>http://www.thetechlabs.com/tutorials/files/flex/asantander/PicLensAway3D/Final/Downloads/away3d.zip</feedburner:origEnclosureLink></item>
		<item>
		<title>Extending the AS3/Flash9 Slideshow with XML</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs/~3/kTabWLNQ_pg/</link>
		<comments>http://www.thetechlabs.com/xml/extending-the-as3flash9-slideshow-with-xml/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 22:34:00 +0000</pubDate>
		<dc:creator>webmaster@thetechlabs.com (The Tech Labs)</dc:creator>
		
		<category><![CDATA[Effects]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[XML]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[caurinas engine]]></category>

		<category><![CDATA[how-to]]></category>

		<category><![CDATA[slideshow]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[tweener]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=105</guid>
		<description><![CDATA[<p>In this second part tutorial we&#8217;re going to add some more features to the slideshow application.</p>
<p>Those would be forwarding and rewinding slides, play and pause the slideshow and linkable slides. If you haven&#8217;t read the first part tutorial yet, you should do it before continue. You can read it here.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/effects/">Effects</a> by Rafael Nuenlist <a href="http://www.thetechlabs.com/xml/extending-the-as3flash9-slideshow-with-xml/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[
<p><a href="http://feedads.googleadservices.com/~a/ftpSm9Qw5qQVrD8ijcgsCqeWqSI/a"><img src="http://feedads.googleadservices.com/~a/ftpSm9Qw5qQVrD8ijcgsCqeWqSI/i" border="0" ismap="true"></img></a></p><p>In this second part tutorial we&#8217;re going to add some more features to <a title="Extended Slideshow" href="http://www.thetechlabs.com/tutorials/files/flash/rnunlist/slideshow2/"  target="_blank">the slideshow application</a>.</p>
<p>Those would be forwarding and rewinding slides, play and pause the slideshow and linkable slides. If you haven&#8217;t read the first part tutorial yet, you should do it before continue. You can read it <a title="Create a AS3 Slideshow with XML Tutorial" href="http://www.thetechlabs.com/xml/create-a-as3-slideshow-with-xml/"  target="_blank">here</a>.</p>
<h3>Requirements</h3>
<p>Adobe Flash CS3</p>
<p><a title="Try / buy" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.adobe.com/products/flash/');" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Try / Buy</a></p>
<p>Sample files:</p>
<p><a title="Source Files" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/cardflip_fp10/CardFlip_FP10_source_files.zip');" href="http://thetechlabs.com/tutorials/files/flash/rnunlist/slideshow2/slideshowprt2.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flash/rnunlist/slideshow2/slideshowprt2.zip');" target="_self">slideshowprt2.zip</a></p>
<h3>Adjust XML structure</h3>
<p>To store the link of each slide, we just add it as an attribute to the xml file, or to be more accurate, on the image nodes. We also set the target window of the link, which might be neccesary to set in some cases. So, our xml is looking now like this:</p>
<pre>&lt;slideshow&gt;
	&lt;image src="images/fly.jpg" desc="Fly" link="http://www.wikipedia.org" target="_self"/&gt;
	&lt;image src="images/mouse.jpg" desc="Computer mouse" link="http://www.google.com" target="_blank"/&gt;
	&lt;image src="images/country.jpg" desc="Country" link="http://www.thetechlabs.com" target="_self"/&gt;
	&lt;image src="images/rope.jpg" desc="Rope" link="http://www.amazon.com" target="_blank"/&gt;
	&lt;image src="images/flower.jpg" desc="Flower" link="http://www.adobe.com" target="_self"/&gt;
&lt;/slideshow&gt;</pre>
<h3>Adding new objects</h3>
<p>Since we know, how the xml looks like, we can move on to the knew stuff on the stage. In the mcInfo movieclip we&#8217;ve added 4 new buttons. Pause/Play and Forward/Rewind, which will later be assigned to event listeners. On the main stage is a invisible button as big as the size of the slides which will be used to open the links defined in the xml.<br />
Alright, that&#8217;s already enough to go on with the coding part.</p>
<h3>Adding new variables</h3>
<p>First of all, we need to add some new variables to our script.</p>
<p>To know, if the slideshow is currently playing or paused, we set a flag:</p>
<pre>var bolPlaying:Boolean = true;</pre>
<p>And we also store the current slide link and target window in a variable:</p>
<pre>var strLink:String = "";
var strTarget:String = "";</pre>
<h3>Init function</h3>
<p>This is all we need for the variable. Now let&#8217;s take a look about what&#8217;s changing in the init function of the slideshow. We added the following two lines at the beginning of the function to prevent the user to click any button as long as the xml file hasn&#8217;t been loaded completely:</p>
<pre>	mcInfo.visible = false;
	btnLink.visible = false;</pre>
<p>We&#8217;ve also changed the function that will be called once the slideTimer event is fired. Now the function nextSlide() will be called, which we&#8217;ll create later:</p>
<pre>	slideTimer.addEventListener(TimerEvent.TIMER, nextSlide);</pre>
<p>On the last line of the initSlideshow() function we add the event listeners for the buttons. The play and button pause event listeners will be assigned to the same function togglePause(). The next and previous button will be asssigned to the nextSlide() and previousSlide() function. And last of all, we connect the invisible link button that covers the slide area with the goToWebsite() function. And since our slideshow will automatically be playing at the beginning, we hide the play button.</p>
<pre>	btnLink.addEventListener(MouseEvent.CLICK, goToWebsite);
	mcInfo.btnPlay.addEventListener(MouseEvent.CLICK, togglePause);
	mcInfo.btnPause.addEventListener(MouseEvent.CLICK, togglePause);
	mcInfo.btnNext.addEventListener(MouseEvent.CLICK, nextSlide);
	mcInfo.btnPrevious.addEventListener(MouseEvent.CLICK, previousSlide);
	mcInfo.btnPlay.visible = false;</pre>
<h3>onXMLLoadComplete function</h3>
<p>Once the xml is completely loaded, we need to show the mcInfo and the button link again. So we add the following two line of code to the function onXMLLoadComplete()</p>
<pre>	mcInfo.visible = true;
	btnLink.visible = true;</pre>
<p>And since our switchSlide() function will now need to have the index number of the slide, we add a zero as the parameter. We&#8217;ll explain the changes in the switchSlide() function later.</p>
<pre>	switchSlide(0);</pre>
<h3>NextSlide/PreviousSide function</h3>
<p>Let&#8217;s take a look at the nextSlide() and previousSlide() functions. They are called when clicking the next and previous button and the nextSlide() function is also called when the Timer event of the sliderTimer has been fired.<br />
The nextSlide() function checks, if there are any slides left to move on. If so, the current switchSlide() function will be called with the next slide index. If there are no more slides left, then the parameter will be zero standing for the first slide.<br />
The previousSlide() function works the same way. If there are slide we can go back, then the switchSlide() function will be called with the previous slide index. If we&#8217;re already on the first slide, then we start the slideshow from the last slide with calling the switchSlide() function with the parameter of the total slide count minus one since the array count begins with zero.</p>
<pre>function nextSlide(e:Event = null):void {
	if(intCurrentSlide + 1 &lt; intSlideCount)
		switchSlide(intCurrentSlide + 1);
	else
		switchSlide(0);

}

function previousSlide(e:Event = null):void {
	if(intCurrentSlide - 1 &gt;= 0)
		switchSlide(intCurrentSlide - 1);
	else
		switchSlide(intSlideCount - 1);
}</pre>
<h3>SwitchSlide function</h3>
<p>Since the nextSlide() and previousSlide() functions are now handling the checking for the slides, we can take out this part in the switchSlide() function.<br />
To prevent the user from clicking too fast on the next and previous button, we check, if the tweener is still fading in the slides. If so, we just ignore the action. We&#8217;re doing this by adding the following if-statement to the first line of the switchSlide() function.</p>
<pre>	if(!Tweener.isTweening(currentContainer)) {</pre>
<p>Now we only need to set the new link and the target of it. This will be done exactly the same way as setting the description of the slide.</p>
<pre>		strLink		= xmlSlideshow..image[intCurrentSlide].@link;
		strTarget	= xmlSlideshow..image[intCurrentSlide].@target;</pre>
<h3>FadeSideIn function</h3>
<p>The fadeSlideIn() function has also a small addition. We check if the slideshow is currently playing and show the number of seconds to the next slide. If the slideshow is paused, we show a status message. The text will be assigned to the lbl_info label.</p>
<pre>	if(bolPlaying) {
		mcInfo.lbl_loading.text = "Next slide in " + TIMER_DELAY / 1000 + " sec.";
	} else {
		mcInfo.lbl_loading.text = "Slideshow paused";
	}</pre>
<h3>OnSlideFadeIn function</h3>
<p>On the onSlideFadeIn() function we now need to check, if the slideshow is playing. If so, we can start the timer again:</p>
<pre>	if(bolPlaying &amp;&amp; !slideTimer.running)
		slideTimer.start();</pre>
<h3>TogglePause function</h3>
<p>The togglePause() function will be called when the user clicks on the play and pause button. First, we check, if the slideshow is playing, if so, we show the play button, set the bolPlaying variable to false, change the status message of the lbl_info label to &#8220;Slideshow paused&#8221; and stop the timer.<br />
If the slideshow is currently paused, we show the pause button, set the bolPlaying variable to true again, show the time to the next slide and restart the timer.</p>
<pre>function togglePause(e:MouseEvent):void {
	if(bolPlaying) {
		mcInfo.btnPlay.visible = true;
		mcInfo.btnPause.visible = false;

		bolPlaying = false;
		mcInfo.lbl_loading.text = "Slideshow paused";
		slideTimer.stop();
	} else {
		mcInfo.btnPlay.visible = false;
		mcInfo.btnPause.visible = true;

		bolPlaying = true;
		mcInfo.lbl_loading.text = "Next slide in " + TIMER_DELAY / 1000 + " sec.";
		slideTimer.reset();
		slideTimer.start();
	}
}</pre>
<h3>GotToWebsite function</h3>
<p>The last function we need to define is the goToWebsite() function. This function will be called once the user clicks on the invisible button. It will check, if the strLink variable is empty or null. If not, the link will be opened.</p>
<pre>function goToWebsite(e:MouseEvent):void {
	if(strLink != "" &amp;&amp; strLink != null) {
		navigateToURL(new URLRequest(strLink), strTarget);
	}
}</pre>
<p>We&#8217;ve already reached the end of the second part of the slideshow tutorial. We hope that you enjoyed reading it and we appreciate any kind of feedback.</p>
<h3>Note</h3>
<p>The feature for clicking the invisible button only works, when you&#8217;re running the flash on a webserver or in the flash sdk.</p>
<h3>Full code with comments</h3>
<pre>// import tweener
import caurina.transitions.Tweener;

// delay between slides
const TIMER_DELAY:int = 5000;
// fade time between slides
const FADE_TIME:Number =	1;

// flag for knowing if slideshow is playing
var bolPlaying:Boolean = true;
// reference to the current slider container
var currentContainer:Sprite;
// index of the current slide
var intCurrentSlide:int = -1;
// total slides
var intSlideCount:int;
// timer for switching slides
var slideTimer:Timer;
// slides holder
var sprContainer1:Sprite;
var sprContainer2:Sprite;
// slides loader
var slideLoader:Loader;
// current slide link
var strLink:String = "";
// current slide link target
var strTarget:String = "";
// url to slideshow xml
var strXMLPath:String = "slideshow-data.xml";
// slideshow xml loader
var xmlLoader:URLLoader;
// slideshow xml
var xmlSlideshow:XML;

function initSlideshow():void {
	// hide buttons, labels and link
	mcInfo.visible = false;
	btnLink.visible = false;

	// create new urlloader for xml file
	xmlLoader = new URLLoader();
	// add listener for complete event
	xmlLoader.addEventListener(Event.COMPLETE, onXMLLoadComplete);
	// load xml file
	xmlLoader.load(new URLRequest(strXMLPath));

	// create new timer with delay from constant
	slideTimer = new Timer(TIMER_DELAY);
	// add event listener for timer event
	slideTimer.addEventListener(TimerEvent.TIMER, nextSlide);

	// create 2 container sprite which will hold the slides and
	// add them to the masked movieclip
	sprContainer1 = new Sprite();
	sprContainer2 = new Sprite();
	mcSlideHolder.addChild(sprContainer1);
	mcSlideHolder.addChild(sprContainer2);

	// keep a reference of the container which is currently
	// in the front
	currentContainer = sprContainer2;

	// add event listeners for buttons
	btnLink.addEventListener(MouseEvent.CLICK, goToWebsite);
	mcInfo.btnPlay.addEventListener(MouseEvent.CLICK, togglePause);
	mcInfo.btnPause.addEventListener(MouseEvent.CLICK, togglePause);
	mcInfo.btnNext.addEventListener(MouseEvent.CLICK, nextSlide);
	mcInfo.btnPrevious.addEventListener(MouseEvent.CLICK, previousSlide);

	// hide play button
	mcInfo.btnPlay.visible = false;
}

function onXMLLoadComplete(e:Event):void {
	// show buttons, labels and link
	mcInfo.visible = true;
	btnLink.visible = true;	

	// create new xml with the received data
	xmlSlideshow = new XML(e.target.data);
	// get total slide count
	intSlideCount = xmlSlideshow..image.length();
	// switch the first slide without a delay
	switchSlide(0);
}

function fadeSlideIn(e:Event):void {
	// add loaded slide from slide loader to the
	// current container
	currentContainer.addChild(slideLoader.content);
	// clear preloader text
	mcInfo.lbl_loading.text = "";

	// check if the slideshow is currently playing
	// if so, show time to the next slide. If not, show
	// a status message
	if(bolPlaying) {
		mcInfo.lbl_loading.text = "Next slide in " + TIMER_DELAY / 1000 + " sec.";
	} else {
		mcInfo.lbl_loading.text = "Slideshow paused";
	}

	// fade the current container in and start the slide timer
	// when the tween is finished
	Tweener.addTween(currentContainer, {alpha:1, time:FADE_TIME, onComplete:onSlideFadeIn});
}

function onSlideFadeIn():void {
	// check, if the slideshow is currently playing
	// if so, start the timer again
	if(bolPlaying &amp;&amp; !slideTimer.running)
		slideTimer.start();
}

function togglePause(e:MouseEvent):void {
	// check if the slideshow is currently playing
	if(bolPlaying) {
		// show play button
		mcInfo.btnPlay.visible = true;
		mcInfo.btnPause.visible = false;

		// set playing flag to false
		bolPlaying = false;
		// set status message
		mcInfo.lbl_loading.text = "Slideshow paused";
		// stop the timer
		slideTimer.stop();
	} else {
		// show pause button
		mcInfo.btnPlay.visible = false;
		mcInfo.btnPause.visible = true;

		// set playing flag to true
		bolPlaying = true;
		// show time to next slide
		mcInfo.lbl_loading.text = "Next slide in " + TIMER_DELAY / 1000 + " sec.";
		// reset and start timer
		slideTimer.reset();
		slideTimer.start();
	}
}

function switchSlide(intSlide:int):void {
	// check if the last slide is still fading in
	if(!Tweener.isTweening(currentContainer)) {
		// check, if the timer is running (needed for the
		// very first switch of the slide)
		if(slideTimer.running)
			slideTimer.stop();

		// change slide index
		intCurrentSlide = intSlide;

		// check which container is currently in the front and
		// assign currentContainer to the one that's in the back with
		// the old slide
		if(currentContainer == sprContainer2)
			currentContainer = sprContainer1;
		else
			currentContainer = sprContainer2;

		// hide the old slide
		currentContainer.alpha = 0;
		// bring the old slide to the front
		mcSlideHolder.swapChildren(sprContainer2, sprContainer1);

		// create a new loader for the slide
		slideLoader = new Loader();
		// add event listener when slide is loaded
		slideLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, fadeSlideIn);
		// add event listener for the progress
		slideLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, showProgress);
		// load the next slide
		slideLoader.load(new URLRequest(xmlSlideshow..image[intCurrentSlide].@src));

		// show description of the next slide
		mcInfo.lbl_description.text = xmlSlideshow..image[intCurrentSlide].@desc;

		// set link and link target variable of the slide
		strLink		= xmlSlideshow..image[intCurrentSlide].@link;
		strTarget	= xmlSlideshow..image[intCurrentSlide].@target;

		// show current slide and total slides
		mcInfo.lbl_count.text = (intCurrentSlide + 1) + &#8221; / &#8221; + intSlideCount + &#8221; Slides&#8221;;
	}
}

function showProgress(e:ProgressEvent):void {
	// show percentage of the bytes loaded from the current slide
	mcInfo.lbl_loading.text = &#8220;Loading&#8230;&#8221; + Math.ceil(e.bytesLoaded * 100 / e.bytesTotal) + &#8220;%&#8221;;
}

function goToWebsite(e:MouseEvent):void {
	// check if the strLink is not empty and open the link in the
	// defined target window
	if(strLink != &#8220;&#8221; &amp;&amp; strLink != null) {
		navigateToURL(new URLRequest(strLink), strTarget);
	}
}

function nextSlide(e:Event = null):void {
	// check, if there are any slides left, if so, increment slide
	// index
	if(intCurrentSlide + 1 &lt; intSlideCount)
		switchSlide(intCurrentSlide + 1);
	// if not, start slideshow from beginning
	else
		switchSlide(0);

}

function previousSlide(e:Event = null):void {
	// check, if there are any slides left, if so, decrement slide
	// index
	if(intCurrentSlide - 1 &gt;= 0)
		switchSlide(intCurrentSlide - 1);
	// if not, start slideshow from the last slide
	else
		switchSlide(intSlideCount - 1);
}

// init slideshow
initSlideshow();</pre>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Extending%20the%20AS3%2FFlash9%20Slideshow%20with%20XML&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Fxml%2Fextending-the-as3flash9-slideshow-with-xml%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Extending%20the%20AS3%2FFlash9%20Slideshow%20with%20XML&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Fxml%2Fextending-the-as3flash9-slideshow-with-xml%2F');"><img src="http://www.thetechlabs.com/wp-content/plugins/add-to-any/share_save_171_16.gif" width="171" height="16" alt="Share/Save/Bookmark"/></a>

	</p><img src="http://feedproxy.google.com/~r/TheTechLabs/~4/kTabWLNQ_pg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/xml/extending-the-as3flash9-slideshow-with-xml/feed/</wfw:commentRss>
		<media:content url="http://feedproxy.google.com/~r/TheTechLabs/~5/gTyha-XLYvo/slideshowprt2.zip" fileSize="4455850" type="application/zip" /><itunes:explicit>no</itunes:explicit><itunes:subtitle> In this second part tutorial we&amp;#8217;re going to add some more features to the slideshow application. Those would be forwarding and rewinding slides, play and pause the slideshow and linkable slides. If you haven&amp;#8217;t read the first part tutorial yet</itunes:subtitle><itunes:author>The Tech Labs</itunes:author><itunes:summary> In this second part tutorial we&amp;#8217;re going to add some more features to the slideshow application. Those would be forwarding and rewinding slides, play and pause the slideshow and linkable slides. If you haven&amp;#8217;t read the first part tutorial yet, you should do it before continue. You can read it here. posted in Effects by Rafael Nuenlist Leave A Comment &amp;copy;2008 The Tech Labs. All Rights Reserved.</itunes:summary><itunes:keywords>Tutorials,adobe,air,flash,flex,webdesign</itunes:keywords><feedburner:origLink>http://www.thetechlabs.com/xml/extending-the-as3flash9-slideshow-with-xml/</feedburner:origLink><enclosure url="http://feedproxy.google.com/~r/TheTechLabs/~5/gTyha-XLYvo/slideshowprt2.zip" length="4455850" type="application/zip" /><feedburner:origEnclosureLink>http://thetechlabs.com/tutorials/files/flash/rnunlist/slideshow2/slideshowprt2.zip</feedburner:origEnclosureLink></item>
		<item>
		<title>Creating a AIR Web Service Package with Flash and AS3- Base Service Class And Simple Twitter API</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs/~3/9GmCJYhawBo/</link>
		<comments>http://www.thetechlabs.com/flash/creating-a-as3-web-service-package-base-service-class-and-simple-twitter-api/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 22:18:47 +0000</pubDate>
		<dc:creator>webmaster@thetechlabs.com (The Tech Labs)</dc:creator>
		
		<category><![CDATA[AIR]]></category>

		<category><![CDATA[Flash]]></category>

		<category><![CDATA[Latest]]></category>

		<category><![CDATA[Webservices]]></category>

		<category><![CDATA[adobe air]]></category>

		<category><![CDATA[adobe flash]]></category>

		<category><![CDATA[API]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[how-to]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=99</guid>
		<description><![CDATA[<p>In this series of tutorials, you will learn the basics of architecting a simple but powerful Web Services Package. We&#8217;ll start off by creating a class which will be the base of all our services and then continue to create a very simple Twitter API.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/air/">AIR</a> by Reynaldo Columna <a href="http://www.thetechlabs.com/flash/creating-a-as3-web-service-package-base-service-class-and-simple-twitter-api/#comments">Leave A Comment</a><br />&copy;2008 <a href="http://www.thetechlabs.com">The Tech Labs</a>. All Rights Reserved.</em></small>]]></description>
			<content:encoded><![CDATA[
<p><a href="http://feedads.googleadservices.com/~a/9L6PBVEAXimnbK-2UmkyhFJF6C0/a"><img src="http://feedads.googleadservices.com/~a/9L6PBVEAXimnbK-2UmkyhFJF6C0/i" border="0" ismap="true"></img></a></p><p>In this series of tutorials, you will learn the basics of architecting a simple but powerful Web Services Package. We&#8217;ll start off by creating a class which will be the base of all our services and then continue to create a very simple Twitter API.<em><strong></strong></em></p>
<p><em><strong>Please note that due to changes in the Twitter cross domain policy, the API we will create in this tutorial will not work online, but works perfectly in an AIR application.</strong></em></p>
<h3>Requirements</h3>
<p><strong>Adobe Flash CS3</strong></p>
<p><a title="Try / buy" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.adobe.com/products/flash/');" href="http://www.adobe.com/products/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flash/');" target="_blank">Try / Buy</a></p>
<p><strong>Adobe Intergrated Runtime (AIR) for Flash CS3</strong></p>
<p><a title="Download AIR for Flash CS3" href="http://www.adobe.com/products/air/develop/flash/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/air/develop/flash/');" target="_blank">Download</a></p>
<p><strong>Source Files</strong></p>
<p><a title="Download Source Files" onclick="javascript:pageTracker._trackPageview('/downloads/tutorials/files/flash/fcarrera/flickrsearchengine/flickrsearchengine_sfiles.zip');" href="http://thetechlabs.com/tutorials/files/flash/Reynaldo/Webservice/AIR Webservice Tutorial.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flash/Reynaldo/Webservice/AIR Webservice Tutorial.zip');" target="_self">Download</a></p>
<h3>Pre-Requesites</h3>
<p>Some experience in creating classes in AS3, if you dont know how to, don&#8217;t worry, you&#8217;ll learn here <img src='http://www.thetechlabs.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Create the package</h3>
<p>The first thing we need to do before actually coding anything is to create our class package. Creating a class package is very simple, we&#8217;ll create it right on our desktop. All you have to do is create a folder and name it &#8220;com&#8221;, that will be the main package. inthe &#8220;com&#8221; folder, create another folder identifying the name of your webservices collection, I&#8217;ll call mine &#8220;reyco1&#8243;. now in the &#8220;reyco1&#8243; folder create another folder called &#8220;webservices&#8221;. That&#8217;s it! package creation complete. Now how easy was that? Very!</p>
<p>Now create create an Actionscript file, name it &#8220;WebService.as&#8221; and save it in the &#8220;webservices&#8221; folder. This is the class that all our apis, such as Twitter API will use to connect to their respective web services. Crack that puppy open and lets get to the coding goodness!</p>
<h3>Coding the main WebService class</h3>
<p>All AS3 classes are contained within a package. We already created our package in the first step, basically a few nested folders. So we&#8217;ll start our class as so:</p>
<pre>package com.reyco1.webservice
{

}</pre>
<p>Now we need to import the classes that we need from flash in order to make our class work:</p>
<pre>package com.reyco1.webservice
{
	import flash.events.*;
	import flash.net.*;
}</pre>
<p>Our class will extend the &#8220;EventDispatcher&#8221; class which means that we will be able to dispatch much needed events. It will have additional properties and methods which we will include in later steps. In the meantime your class should look like this:</p>
<pre>package com.reyco1.webservice
{
	import flash.events.*;
	import flash.net.*;

	public class WebService extends EventDispatcher
	{

    }

}</pre>
<p>Now we create the variables that we will need in order to connect to the online web services. We&#8217;ll need a URLRequest, a URLLoader and a URLVariables along with a generic data variable that will hold information returned from the web service. We want to make this data variable public so that it can be accessed from outside the class:</p>
<pre>package com.helix.webservice
{
	import flash.events.*;
	import flash.net.*;

	public class WebService extends EventDispatcher
	{

		private var request:URLRequest;
		private var loader:URLLoader;
		private var variables:URLVariables;
		public var data:*

    }

}</pre>
<p>Now that we have all the variables we need, we can go ahead and create our constructor. The class constructor is a special method always named the same name as the class. Constructors can accept arguments or not. Our&#8217;s will accept one, an HTTP Request (I&#8217;ll explain in a bit). We&#8217;ll call the EventDispatcher constructor by calling the &#8220;super&#8221; method and then set our request variable to accept the HTTP Request:</p>
<pre>package com.reyco1.webservice
{
	import flash.events.*;
	import flash.net.*;

	public class WebService extends EventDispatcher
	{

		private var request:URLRequest;
		private var loader:URLLoader;
		private var variables:URLVariables;
		public var data:*

		public function WebService($servicePath:String)
		{
        	super();
			request = new URLRequest($servicePath);
		}
    }
}</pre>
<p>Now we&#8217;ll create our one and only method. This is the method that will make the call to the webservice. Our method will accept 2 arguments: the first is a &#8220;method&#8221; (String); we can set this method to be either &#8220;POST&#8221; or &#8220;GET&#8221;, ours will default to &#8220;POST&#8221;. Usually web services will tell you which method to use in order to access their information. The second argument is &#8220;arguments&#8221; (Object); This will hold any parameters that you would need to make your service call. Again, web services will tell you if you need to send any additional information with your call, ours defaults to null.</p>
<pre>package com.reyco1.webservice
{
	import flash.events.*;
	import flash.net.*;

	public class WebService extends DispatchExtension
	{

		private var request:URLRequest;
		private var loader:URLLoader;
		private var variables:URLVariables;
		public var data:*

		public function WebService($servicePath:String)
		{
			request = new URLRequest($servicePath);
		}

		/**
		 * Makes the web service call
		 * @param $method either POST or GET. POST is set as default
		 * @param $arguments any parameters or variables that you need to make with your web service call
		 *
		 */
		public function call($method:String="POST", $arguments:Object=null):void
		{
			variables = new URLVariables();
			if($arguments != null){
				for (var i:* in $arguments){
					variables[i] = $arguments[i];
				}
				request.data = variables;
			}
			request.method = $method.toUpperCase();
			loader = new URLLoader(request);
			loader.addEventListener(Event.COMPLETE, handleRequestLoaded);
			loader.addEventListener(IOErrorEvent.IO_ERROR, handleRequestError);
			loader.load(request);
		}
    }
}</pre>
<p>Now let me explain what&#8217;s going on up there. Basically we set up our URLVariables by recursing through the &#8220;$arguments&#8221; parameter if it&#8217;s not set to null and set it to the &#8220;data&#8221; proerty or our URLRequest. Then we specify the call method by setting the URLRequest&#8217;s &#8220;method&#8221; property to the &#8220;$method&#8221; parameter. We then continue to set up out URLLoader instance by adding the COMPLETE and IOErrorEvent event listeners. Finally we make the service call by executing the URLLoader&#8217;s call method and passing it the URLRequest.</p>
<p>Now we create the handlers for our event listeners:</p>
<pre>package com.reyco1.webservice
{
	import flash.events.*;
	import flash.net.*;

	public class WebService extends EventDispatcher
	{

		private var request:URLRequest;
		private var loader:URLLoader;
		private var variables:URLVariables;
		public var data:*

		public function WebService($servicePath:String)
		{
			request = new URLRequest($servicePath);
		}

		/**
		 * Makes the web service call
		 * @param $method either POST or GET. POST is set as default
		 * @param $arguments any parameters or variables that you need to make with your web service call
		 *
		 */
		public function call($method:String="POST", $arguments:Object=null):void
		{
			variables = new URLVariables();
			if($arguments != null){
				for (var i:* in $arguments){
					variables[i] = $arguments[i];
				}
				request.data = variables;
			}
			request.method = $method.toUpperCase();
			loader = new URLLoader(request);
			loader.addEventListener(Event.COMPLETE, handleRequestLoaded);
			loader.addEventListener(IOErrorEvent.IO_ERROR, handleRequestError);
			loader.load(request);
		}

		private function handleRequestLoaded($event:Event):void
		{
			data = $event.target.data;
			this.dispatchEvent(new Event(&#8221;RESULT&#8221;, false));
		}

		private function handleRequestError($event:IOErrorEvent):void
		{
			data = {};
			this.dispatchEvent(new Event(&#8221;FAULT&#8221;, false));
		}

	}
}</pre>
<p>In the handlers, if the call is successfull, it sets the data variable to the data that the web service returns and fires a &#8220;RESULT&#8221; event. If the call is unsuccessful, set the data to an empty object and fires teh &#8220;FAULT&#8221; event. Now we&#8217;ll add getter and setter functions so that we may be able to dynamically set the web service path whenever we want.</p>
<pre>package com.reyco1.webservice
{
	import flash.events.*;
	import flash.net.*;

	public class WebService extends EventDispatcher
	{

		private var request:URLRequest;
		private var loader:URLLoader;
		private var variables:URLVariables;
		public var data:*

		public function WebService($servicePath:String)
		{
			request = new URLRequest($servicePath);
		}

		/**
		 * Makes the web service call
		 * @param $method either POST or GET. POST is set as default
		 * @param $arguments any parameters or variables that you need to make with your web service call
		 *
		 */
		public function call($method:String="POST", $arguments:Object=null):void
		{
			variables = new URLVariables();
			if($arguments != null){
				for (var i:* in $arguments){
					variables[i] = $arguments[i];
				}
				request.data = variables;
			}
			request.method = $method.toUpperCase();
			loader = new URLLoader(request);
			loader.addEventListener(Event.COMPLETE, handleRequestLoaded);
			loader.addEventListener(IOErrorEvent.IO_ERROR, handleRequestError);
			loader.load(request);
		}

		private function handleRequestLoaded($event:Event):void
		{
			data = $event.target.data;
			this.dispatchEvent(new Event(&#8221;RESULT&#8221;, false));
		}

		private function handleRequestError($event:IOErrorEvent):void
		{
			data = {};
			this.dispatchEvent(new Event(&#8221;FAULT&#8221;, false));
		}

		public function set servicePath($path:String):void
		{
			request = new URLRequest($path);
		}

		public function get servicePath():String
		{
			return request.url;
		}

	}
}</pre>
<p>That&#8217;s basically all we need for our base WebService calss! Was it easy? Hope so <img src='http://www.thetechlabs.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> lets fire it up by using it in a simple Twitter API!</p>
<h3>Using the newly created WebService class to make a simple Twitter API</h3>
<p>Create a new Actionscript file, name it &#8220;Twitter&#8221; and save it to the webservices folder. We want this class to fire events also, so lets start off by extending the EventDispatcher class. Remember also to import the flash events package and our WebService class too:</p>
<pre>package com.reyco1.webservice
{
	import com.reyco1.webservice.WebService;
	import flash.events.*;

	public class Twitter extends EventDispatcher
	{
    }

}</pre>
<p>Cool, let&#8217;s create a static private var that will hold an HTTP Status method provided by the online Twitter API. You can find all the Twiiter methods over at the Twitter RESR API Docunebtation here: http://apiwiki.twitter.com/REST+API+Documentation#HTTPStatusCodes. We&#8217;re going to use only one for now. The call to get all the Tweets on the public timeline.</p>
<p>We&#8217;re also going to need a private variable to represent our WebService class and a public array variable which will hold the parsed xml returned byt Twitter:</p>
<pre>package com.reyco1.webservice
{
	import com.reyco1.webservice.WebService;
	import flash.events.*;

	public class Twitter extends EventDispatcher
	{

		private static var PUBLIC_TIMELINE:String = "http://twitter.com/statuses/public_timeline.xml";

		private var twitterService:WebService;
		public var result:Array;

        }
    }
}</pre>
<p>Ok, now let&#8217;s set up our constructor. In the constructor we will set up our instance of the WebService class. Remeber that the WebService class needs to accept a service path in it&#8217;s constructor, so we&#8217;ll pass it our PUBLIC_TIMELINE path as default. We also set the result array to an empty array;</p>
<pre>package com.reyco1.webservice
{
	import com.reyco1.webservice.WebService;
	import flash.events.*;

	public class Twitter extends EventDispatcher
	{

		private static var PUBLIC_TIMELINE:String = "http://twitter.com/statuses/public_timeline.xml";

		private var twitterService:WebService;
		public var result:Array;

		public function Twitter()
		{
			twitterService = new WebService(Twitter.PUBLIC_TIMELINE);
			twitterService.addEventListener("RESULT", handleResult);
			twitterService.addEventListener("FAULT", handleFault);

			result = [];
		}
    }
}</pre>
<p>before we set up the handlers for the events fired from the WebService class, let&#8217;s create the method which will make the request for the public timeline to Twitter:</p>
<pre>package com.reyco1.webservice
{
	import com.reyco1.webservice.WebService;
	import flash.events.*;

	public class Twitter extends EventDispatcher
	{

		private static var PUBLIC_TIMELINE:String = "http://twitter.com/statuses/public_timeline.xml";

		private var twitterService:WebService;
		public var result:Array;

		public function Twitter()
		{
			twitterService = new WebService(Twitter.PUBLIC_TIMELINE);
			twitterService.addEventListener("RESULT", handleResult);
			twitterService.addEventListener("FAULT", handleFault);

			result = [];
		}

		public function requestPublicTimeline():void
		{
			twitterService.servicePath = Twitter.PUBLIC_TIMELINE;
			twitterService.call();
		}
    }
}</pre>
<p>What we&#8217;re doing is dynamically setting the service path on the Webservices class. Now, you may be asking yourself, &#8220;didn&#8217;t we just add that path up in the constructor?&#8221;, the answer is, yes. Never the less, it is good practice for us to set it up here again, basically because later on when we add new methods, we&#8217;ll have to set it to the new service path anyway, so might as well get used to it from now <img src='http://www.thetechlabs.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Afther the path is set, then we then execute the call method of our WebService class. Nothig is going to happen unless we add our event handlers, so let&#8217;s get to it!</p>
<pre>package com.reyco1.webservice
{
	import com.reyco1.webservice.WebService;
	import flash.events.*;

	public class Twitter extends EventDispatcher
	{

		private static var PUBLIC_TIMELINE:String = "http://twitter.com/statuses/public_timeline.xml";

		private var twitterService:WebService;
		public var result:Array;

		public function Twitter()
		{
			twitterService = new WebService(Twitter.PUBLIC_TIMELINE);
			twitterService.addEventListener("RESULT", handleResult);
			twitterService.addEventListener("FAULT", handleFault);

			result = [];
		}

		public function requestPublicTimeline():void
		{
			twitterService.servicePath = Twitter.PUBLIC_TIMELINE;
			twitterService.call();
		}

		private function handleFault($event:Event):void
		{
			result = [];
			this.dispatchEvent(new Event(&#8221;FAULT&#8221;));
		}

		private function handleResult($event:Event):void
		{
			var myResult:XML = new XML(twitterService.data);
			result = parseResult(myResult);
			this.dispatchEvent(new Event(&#8221;RESULT&#8221;));
		}
    }
}</pre>
<p>Nothing too fancy in the fault event handler. Basically, all it does is is just set the reult array to an ampty array and fires a new Fault event. Now, the good stuff is in the result event handler. The response we get from Twitter will be a String in an XML format, so once it arrives, we need make sure flash reads it as XML. Once that is done, we pass it to a method named &#8220;parseResult&#8221; which we will be seeing in the next step. Essentially, all the &#8220;parseResult&#8221; method does is take the xml returned from Twitter and parse it into an array of objects, better known as a &#8220;Collection&#8221;. Once the XML is parsed, it is set as the &#8220;result&#8221; array and a &#8220;RESULT&#8221; event is fired. Let&#8217;s see that crazy &#8220;parseResult&#8221; method:</p>
<pre>package com.reyco1.webservice
{
	import com.reyco1.webservice.WebService;
	import flash.events.*;

	public class Twitter extends EventDispatcher
	{

		private static var PUBLIC_TIMELINE:String = "http://twitter.com/statuses/public_timeline.xml";

		private var twitterService:WebService;
		public var result:Array;

		public function Twitter()
		{
			twitterService = new WebService(Twitter.PUBLIC_TIMELINE);
			twitterService.addEventListener("RESULT", handleResult);
			twitterService.addEventListener("FAULT", handleFault);

			result = [];
		}

		public function requestPublicTimeline():void
		{
			twitterService.servicePath = Twitter.PUBLIC_TIMELINE;
			twitterService.call();
		}

		private function handleResult($event:Event):void
		{
			var myResult:XML = new XML(twitterService.data);
			result = parseResult(myResult);
			this.dispatchEvent(new Event(&#8221;RESULT&#8221;));
		}

		private function handleFault($event:Event):void
		{
			result = [];
			this.dispatchEvent(new Event(&#8221;FAULT&#8221;));
		}

		private function parseResult($result:XML):Array
		{
			var objectArray:Array = [];
			var xml:XML = $result
			var xmllist:XMLList = xml.children();

			for(var a:Number = 0; a &lt; xmllist.length(); a++){
				var object:Object = {};
				for(var b:Number = 0; b&lt; xmllist[a].children().length(); b++){
					var item:XML = xmllist[a].children()[b];
					if(item.localName().toString() == &#8220;user&#8221;){
						var userObject:Object = {};
						for(var c:Number = 0; c &lt; item.children().length(); c++){
							userObject[item.children()[c].localName().toString()] = item.children()[c].toString()
						}
						object[item.localName()] = userObject;
					}else{
						object[item.localName()] = item.toString();
					}
				}
				objectArray.push(object);
			}
			return objectArray;
		}
	}
}</pre>
<p>With the &#8220;parseResult&#8221; method, each node in the XML will be parsed into an object containing the following values:</p>
<pre>id
in_reply_to_status_id
source
created_at
user
  -- name
  -- url
  -- screen_name
  -- description
  -- followers_count
  -- id
  -- protected
  -- profile_image_url
  -- location
in_reply_to_user_id
text
favorited
truncated</pre>
<p>I think it&#8217;s time we test ride this puppy! Let&#8217;s get to it!</p>
<h3>Creating a Twitter Application with our newly created Twitter API</h3>
<p>Crack open an fla file and set the stage dimensions to 310 by 400. We&#8217;ll start off by creating a container for each Tweet. The container movieclip will hold the users profile image and a textfield to display the user&#8217;s tweet. Each of a users profile image is 48 x 48, so create a square on the stage 48 x 48 and create a static text field which says &#8220;LOADING&#8221; and place it right at the center of the box. Now convert the whole thing into a MovieClip and instance name it &#8220;imageContainer&#8221;;</p>
<p><img class="alignnone size-full wp-image-101" title="image001" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image001.png" alt="" width="141" height="119" /></p>
<p><img src="images/image001.png" border="0" alt="" /></p>
<p>Now create a dynamic text field with the following properties:</p>
<p><img class="alignnone size-full wp-image-103" title="image002" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image002.png" alt="" width="500" height="89" /></p>
<p><img src="images/image002.png" border="0" alt="" /></p>
<p>Set the text field right next to the imageContainer and create a MovieClip out of the whole thing. So essentially at this point you should have ONE MovieClip on the stage. This movie clip should contain an 48 x 48 MovieClip instance named &#8220;imageContainer&#8221; and a dynamic text field instance named &#8220;twitTxt&#8221;</p>
<p><img class="alignnone size-full wp-image-104" title="image003" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image003.png" alt="" width="372" height="101" /></p>
<p><img src="images/image003.png" border="0" alt="" /></p>
<p>Drag another 5 instances of the newly created movie clip from the library and drop them on the stage and align them one under the other like shown below and instance name then item0, item1, item2, item3, item4 and item5:</p>
<p><img class="alignnone size-full wp-image-102" title="image004" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/image004.png" alt="" width="297" height="310" /></p>
<p><img src="images/image004.png" border="0" alt="" /></p>
<p>That&#8217;s it for the timeline stuff. Select the first frame and open up your actions panel. The first thing we need to do is import our Twitter class;</p>
<pre>import com.reyco1.webservice.Twitter</pre>
<p>Now we create an instance of our Twitter API and have it listen to the &#8220;RESULT&#8221; event:</p>
<pre>import com.reyco1.webservice.Twitter

var twitter:Twitter = new Twitter();
twitter.addEventListener("RESULT", handleResult);</pre>
<p>Let&#8217;s set up the handler for the result event. In the handler we pass the first 6 of the objects in the result array to a &#8220;populateItem&#8221; method along with its index. Let&#8217;s take a look at the event handler and then we&#8217;ll see what that &#8220;populateItem&#8221; method looks like.</p>
<pre>import com.reyco1.webservice.Twitter

var twitter:Twitter = new Twitter();
twitter.addEventListener("RESULT", handleResult);

function handleResult($event:Event):void
{
	var result:Array = twitter.result;
	for(var a:Number = 0; a &lt; 6; a++){
		populateItem(a, result[a]);
	}
}</pre>
<p>Below we&#8217;ve added the &#8220;populateItem&#8221; method. Basically, this method adds the tweet to the text field in the item on stage along with adding the image to it&#8217;s imageContainer.</p>
<pre>import com.reyco1.webservice.Twitter

var twitter:Twitter = new Twitter();
twitter.addEventListener("RESULT", handleResult);

function handleResult($event:Event):void
{
	var result:Array = twitter.result;
	for(var a:Number = 0; a &lt; 6; a++){
		populateItem(a, result[a]);
	}
}

function populateItem($itemIndex:Number, $twitObject:Object):void
{
	this["item"+$itemIndex].twitText.text = $twitObject.text;
	var imageLoader:Loader = new Loader();
	this["item"+$itemIndex].imageContainer.addChild(imageLoader);
	var imagePath:URLRequest = new URLRequest($twitObject.user.profile_image_url);
	imageLoader.load(imagePath);
}</pre>
<p>Now all we have to do is call the &#8220;requestPublicTimeline&#8221; method of our Twitter API and we&#8217;re DONE!!</p>
<pre>import com.reyco1.webservice.Twitter

var twitter:Twitter = new Twitter();
twitter.addEventListener("RESULT", handleResult);

function handleResult($event:Event):void
{
	var result:Array = twitter.result;
	for(var a:Number = 0; a &lt; 6; a++){
		populateItem(a, result[a]);
	}
}

function populateItem($itemIndex:Number, $twitObject:Object):void
{
	this["item"+$itemIndex].twitText.text = $twitObject.text;
	var imageLoader:Loader = new Loader();
	this["item"+$itemIndex].imageContainer.addChild(imageLoader);
	var imagePath:URLRequest = new URLRequest($twitObject.user.profile_image_url);
	imageLoader.load(imagePath);
}

twitter.requestPublicTimeline();</pre>
<h3>Publishing your file as an AIR application</h3>
<p>Publishing a flash file as an AIR application cannot be any easier:</p>
<ul>
<li>Download the runtime installation file.</li>
<li>Double-click the runtime installation file.</li>
<li>In the installation window, follow the prompts to complete the installation.</li>
</ul>
<p>Once installed, follow these steps:</p>
<ul>
<li>Open your Flash FLA file.</li>
<li>If you’re opening a new Flash File (ActionScript 3.0), save it. If you don’t save it, a warning appears when you do the next step.</li>
<li>Select Commands &gt; AIR - Application And Installer Settings. An alert box appears, asking if you want to convert the file to Adobe AIR publish settings.</li>
<li>Click OK to convert the FLA file to Adobe AIR publish settings. The AIR - Application And Installer Settings dialog box appears.</li>
</ul>
<p>Simply publish your and all should work! I hope you have enjoyed this article and have been able to learn lots of stuff! In the next few tutorials, I&#8217;ll be adding more complex methods to our Twitter API and Hopefully at the end of the series, we&#8217;ll have a fully working Twitter Application!</p>
<p class="addtoany_share_save_container">
    <a class="a2a_dd addtoany_share_save" onmouseover="a2a_show_dropdown(this)" onmouseout="a2a_onMouseOut_delay()" href="http://www.addtoany.com/share_save?sitename=The%20Tech%20Labs&amp;siteurl=http%3A%2F%2Fwww.thetechlabs.com%2F&amp;linkname=Creating%20a%20AIR%20Web%20Service%20Package%20with%20Flash%20and%20AS3-%20Base%20Service%20Class%20And%20Simple%20Twitter%20API&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Fflash%2Fcreating-a-as3-web-service-package-base-service-class-and-simple-twitter-api%2F" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.addtoany.com/share_save?sitename=The%20Tech%20Lab