<?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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>The Tech Labs » Flex</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>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feedproxy.google.com/TheTechLabs_flex" type="application/rss+xml" /><item>
		<title>Simulating PicLens with Flex and Away3D – Part 3</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_flex/~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>Alejandro Santander</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>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_flex/~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>
		<feedburner:origLink>http://www.thetechlabs.com/xml/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-3/</feedburner:origLink></item>
		<item>
		<title>Simulating PicLens with Flex and Away3D – Part 2</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_flex/~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>Alejandro Santander</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><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_flex/~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>
		<feedburner:origLink>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-2/</feedburner:origLink></item>
		<item>
		<title>Simulating PicLens with Flex and Away3D – Part 1</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_flex/~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>Alejandro Santander</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>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_flex/~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>
		<feedburner:origLink>http://www.thetechlabs.com/3d/simulating-piclens-with-flex-and-away3d-%e2%80%93-part-1/</feedburner:origLink></item>
		<item>
		<title>Setting up Away3d with Flex</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_flex/~3/0nfazOb2w54/</link>
		<comments>http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/#comments</comments>
		<pubDate>Sun, 31 Aug 2008 23:15:19 +0000</pubDate>
		<dc:creator>Alejandro Santander</dc:creator>
		
		<category><![CDATA[3D]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[3D Engine]]></category>

		<category><![CDATA[animation]]></category>

		<category><![CDATA[API]]></category>

		<category><![CDATA[as3]]></category>

		<category><![CDATA[Away3D]]></category>

		<category><![CDATA[cubes]]></category>

		<category><![CDATA[how-to]]></category>

		<category><![CDATA[object]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=92</guid>
		<description><![CDATA[<p>In this tutorial I will show you how to set up a simple away3d scene, taking advantage of FlexBuilder&#8217;s enhanced programming interface. I will also take advantage of the tutorial to introduce Flex to Flash developers who have never used it.</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/setting-up-away3d-with-flex/#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>In  this tutorial I will show you how to set up a simple away3d scene, taking  advantage of FlexBuilder&#8217;s enhanced programming interface. I will also take  advantage of the tutorial to introduce Flex to Flash developers who have never  used it.</p>
<p>The  result is <a title="See the Demo" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/Setting%20up%20away3d%20with%20Flex/Demo/"  target="_blank">THIS</a> and you can download the  source <a title="Download the source files" href="http://www.thetechlabs.com/tutorials/files/flex/asantander/Setting up away3d with Flex/source_files.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/flex/asantander/Setting up away3d with Flex/source_files.zip');" target="_blank">HERE</a>.</p>
<h3>Requirements:</h3>
<p><strong>Flex 3</strong></p>
<p><a title="Try/Buy" 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">Try/Buy</a></p>
<h3>Pre Requisites:</h3>
<p>-  Intermediate programming skills.</p>
<p>-  Some knowledge and understanding of the Actionscript 3 language.</p>
<p>-  Basic principles of OOP (Object Oriented Programming).</p>
<h3>Step 0</h3>
<p>NOTE: you may skip this if you&#8217;re already  familiar with Flex, and know what away3d is.</p>
<p>This  tutorial deals with 2 technologies. Away3d and Flex. Before we start, let me  say a few words about them:</p>
<p>Away3d  is an open source 3d engine designed to boost flash based applications with  powerful 3d capabilities. There are a few other3d engines out there, such as  Papervision3d, Sandy3d, Alternativa3d and more, each with its pros and cons. I  personally useAway3d, because I think its the most apt engine at this time.</p>
<p>Flex  is something most developers that come from the Flash arena fear pretty badly.  What is it?? Well, the thing is that Flex can be used in complement with Flash  for Actionscript projects very easily, providing them with powerful programming  tools.Let me list a few:</p>
<p>-  When you create a new variable and introduce the &#8220;:&#8221; character, Flex  lists all available object types, and if you press enter after you found the  appropriate type, flex automatically creates the import statements for you.  This is extremely handy, since you don’t need to remember what package an  object belongs to, nor consult the API reference to write the appropriate import  statement.</p>
<p>-  Flex detects errors while you code! That is, you don’t need to compile your  project to see if you made mistakes. This is simple magical.</p>
<p>-  By pressing F1 over an object type, Flex takes you to the help section for that  type, and if you press F3, it takes you right to the definition of that object.  This dramatically accelerates the learning process of any given API.</p>
<p>Well,  enough, lets get started. I just wanted to emphasize on the great help that Flex  provides when dealing with AS3 development. Personally, once I got over the  scary, &#8220;what the hell is flex&#8221; phase, I cant imagine working without  it now.</p>
<h3>Step 1</h3>
<p>Download  the FlexBuilder 3 fully functional 60 day trial from adobe and install it. You  just need to create an Adobe account and download the trial from this <a title="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex" href="https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex" onclick="javascript:pageTracker._trackPageview('oclicks/https://www.adobe.com/cfusion/tdrc/index.cfm?product=flex');" target="_blank">link</a>.</p>
<p>Then  download the latest <a title="Away3D API" href="http://away3d.com/downloads" onclick="javascript:pageTracker._trackPageview('oclicks/http://away3d.com/downloads');" target="_blank">Away3d API</a>.</p>
<h3>Step 2</h3>
<p>Create  a folder somewhere in your hard drive that will work as your workspace for  initial Away3d experimentation. This folder will be able to hold many flex  projects.</p>
<p>Open  flex, select file -&gt; switch workspace, and point flex to the folder you just  created.</p>
<p>Now,  right click on the Flex Navigator panel, and select new “Actionscript Project”.</p>
<p><img class="aligncenter size-full wp-image-93" title="Figure 1" src="http://www.thetechlabs.com/wp-content/uploads/2008/08/img1.jpg" alt="Figure 1" width="500" height="500" /></p>
<p>Once  the dialog shows up, enter Away3dProject as the project name and click finish.</p>
<p>If  you go back to your HD file browser and see the folder you created initially,  you can notice that flex created an inner folder for this project. The Flex  Navigator pretty much works like a regular file browser, listing the projects  you have on that workspace and the files that conform them.</p>
<h3>Step 3</h3>
<p>Go  to your away3d download in your file browser and copy the folder in it named  away3d. Come back to the flex navigator, right click on the Away3dProjectfolder  icon and paste.</p>
<p><img class="aligncenter size-full wp-image-94" title="Figure 2" src="http://www.thetechlabs.com/wp-content/uploads/2008/08/img2.jpg" alt="Figure 2" width="500" height="500" /></p>
<p>That’s  it! Flex is ready to work with the Away3d engine.</p>
<h3>Step 4</h3>
<p>Its  time to code. Right click the Away3dProject folder icon in the Flex Navigator  again, and choose new “Actionscript  class”, name itAway3dScene and click finish. This should automatically open  the file in the coding area, to the right of the Flex Navigator.</p>
<p>The  class should extend Sprite, since this class will contain all away3d stuff and  be treated as any other graphic object. Start by placing this code in it:</p>
<pre>package
{
     import flash.display.Sprite;

     public class Away3dScene extends Sprite
     {
           public function Away3dScene()
           {
                graphics.beginFill(0xFF0000);
                graphics.drawRect(0, 0, 100,  100);
                graphics.endFill();
           }
     }
}</pre>
<h3>Step 5</h3>
<p>Double  click the other .as file in the navigator named Away3dProject.as. Notice that  this one has a little green triangle attached to its icon. This simply states  that when you compile the application, this is the base class, what’s known in  Flash as the Document class.</p>
<p>Place  this code in it:</p>
<pre>package
{
     import flash.display.Sprite;
     import flash.display.StageScaleMode;
     import flash.display.StageAlign;

     public class Away3dProject extends Sprite
     {
           public function Away3dProject()
           {
                stage.scaleMode =  StageScaleMode.NO_SCALE;
                stage.align =  StageAlign.TOP_LEFT;

                var scene:Sprite = new  Away3dScene();
                addChild(scene);
           }
     }
}</pre>
<p>Lines  11 to 12 simply set a couple of stage properties that allow us to be in control  of how the stage is scaled and positioned in the browser, and lines 4 to 5  provide the appropriate import statements for this.</p>
<p>Lines  14 to 15, create an instance of the Away3dScene (which is a Sprite!) and add it  to the stage.</p>
<h3>Step 6</h3>
<p>Above  the Flex Navigator is a little green button with a white play icon in it. This  is what you press to compile the application.Go ahead and compile it. Flex will  open your default web browser and run the demo in it.</p>
<p>Once  you compiled, you should simply see a red square, at the top left corner of the  browser.</p>
<p><img class="aligncenter size-full wp-image-96" title="Figure 3" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/img3.jpg" alt="Figure 3" width="500" height="500" /></p>
<p>Hmm…  What? Well, I just wanted to show you how a class that will be holding all the  3d content can be a Sprite itself, and you can treat it as such, 100%.Alright,  delete lines 9 through 11 of Away3dScene.as and lets get started with the 3d  stuff.</p>
<h3>Step 7</h3>
<p>Now,  lets create an event listener on the constructor that will call the  initialization of the scene when the instance of Away3dScene  is added to the stage. The initialization will be a method called “init()”,  consisting of two sub methods and an event  listener registration for enterframe events.</p>
<p>In  Away3dScene.as, modify the constructor and add the other methods under it as  follows:</p>
<pre>public  function Away3dScene()
{
     addEventListener(Event.ADDED_TO_STAGE,  init, false, 0, true);
}

private  function init(evt:Event):void
{
     removeEventListener(Event.ADDED_TO_STAGE,  init);

     init3dScene();
     init3dObjects();
     addEventListener(Event.ENTER_FRAME,  renderScene);
}

private  function init3dScene():void
{

}

private  function init3dObjects():void
{

}

private  function renderScene(evt:Event):void
{

}</pre>
<p>Make  sure that as you type &#8220;evt:Eve&#8230;&#8221;, press enter when the flex  auto complete dialogue box shows “Event”on one of the function declaration  parameters of “init()” or “renderScene()”. Doing this will ensure that Flex  creates the appropriate import statements automatically.</p>
<p><img class="aligncenter size-full wp-image-97" title="Figure 4" src="http://www.thetechlabs.com/wp-content/uploads/2008/09/img4.jpg" alt="Figure 4" width="500" height="500" /></p>
<p>Now,  why wait until the instance is added to the stage to call the “init()” method?  Its a simple matter actually: In “init3dScene()” we will set up the core of the  3d environment, and when doing this, we need to know the dimensions of the  stage&#8230; and we wouldn’t be able to know this if the sprite (or  Away3dScene instance) wasn’t yet added to the stage! In “init3dObjects()”, as  the name of the method makes it pretty obvious, we will create a bunch of  objects and place them inside the 3d environment.</p>
<h3>Step 8</h3>
<p>The  3d scene will have 3 main elements: a Scene3D object, a Camera3D object, and View3D.  These are all very important classes within the Away3d API. Declare instances  of these as private variables in Away3dScene.as:</p>
<pre>private  var scene:Scene3D;
private  var camera:Camera3D;
private  var view:View3D;</pre>
<p>Make  sure you rewrite this and not just paste it to make sure that Flex imports the  correct classes. Don’t worry, you’ll get used to this ;D</p>
<h3>Step 9</h3>
<p>Lets  build the 3d environment. Place the following code within the “init3dScene()”  method:</p>
<pre>scene  = new Scene3D();

camera  = new Camera3D();
camera.zoom  = 10;
camera.focus  = 200;
camera.z  = -3000;
camera.lookAt(new  Number3D(0, 0, 0));

view  = new View3D();
view.scene  = scene;
view.camera  = camera;
view.clip  = new RectangleClipping(-stage.stageWidth/2, -stage.stageHeight/2,  stage.stageWidth/2, stage.stageHeight/2);
view.x  = stage.stageWidth/2;
view.y  = stage.stageHeight/2;
addChild(view);</pre>
<p>Now,  lets go over those lines slowly. First, we created &#8220;scene&#8221;, an instance  of Scene3D. This is actually the container of all the objects of the 3d  environment. Those of you who are familiar with 3D, it is the main node of the  environment. Then, we create a camera as an instance of Camera3D. This is pretty  intuitive; its the object we will move around and that will represent us, the  spectator, inside the 3denvironment. Notice the parameters of the camera that  are set immediately after its initialization. If you type &#8220;camera.&#8221;,  Flex will automatically bring up the auto complete dialogue box and show you all  available methods and parameters that you can use for this object, so, if you  want to see if the camera has a &#8220;y&#8221; property, type “camera.” And see  if it shows up&#8230; Its pretty handy, and we&#8217;ve never looked at the API reference  yet.</p>
<p>Finally,  we create an instance of View3D. The view will represent the graphical output  of the situation of our camera looking at our scene or environment. It is an  object that extends sprite, and that represents what we see.The first 2  parameters of the view are the scene and the camera. What we are doing here is  just telling it what camera and what scene</p>
<p>It  will refer to.</p>
<p>Then,  we clip and position the view. The clipping part is telling the view which are  its limits in x, y, width and height, and hence setting the center of  coordinates. The positioning part just places the view as if it were a normal  sprite.</p>
<p>Oh,  and of course, the view is added to the display, since it is a graphical  element after all.</p>
<p>Note:  To avoid confusion, Away3dScene (our class) and View3D both extend Sprite,  Scene3D doesn’t! Away3dScene is just a class that we are using to place all the  3d stuff in, it has nothing to do with Scene3D. Sorry about that, I don’t know  why but I see I got used to naming things this way.</p>
<h3>Step 10</h3>
<p>So,  the 3d environment is set. Lets put some stuff in it. I’ve decided to make a  little nested loop structure, in order to make this tutorial a little fancier,  but don’t mind this, what really matters is the creation of the 3d objects:</p>
<pre>var i:uint;
var j:uint;
var  k:uint;
var  spacing:Number = 250;
var  quantity:uint = 3;
var  offset:Number = (quantity-1)*spacing/2;
for(i  = 0; i&lt;quantity; i++)
{
     for(j = 0; j&lt;quantity; j++)
     {
           for(k = 0; k&lt;quantity; k++)
           {
                var cube:Cube = new Cube();
                cube.x = i*spacing - offset;
                cube.y = j*spacing - offset;
                cube.z = k*spacing - offset;
                scene.addChild(cube);
           }
     }
}</pre>
<p>We  are creating the cube instance and then adjusting its parameters the same way  as we created the scene and camera before. To see what kind of primitives you  can create with Away3d, bookmark the away API reference <a href="http://away3d.com/livedocs/" onclick="javascript:pageTracker._trackPageview('oclicks/http://away3d.com/livedocs/');">http://away3d.com/livedocs/</a>, check out the primitives package and have the API  handy for future experiments.</p>
<h3>Step 11</h3>
<p>So,  what’s left?</p>
<p>We  just need to implement on more thing and were done. Add this line at the end of  the “init()” method:</p>
<pre>addEventListener(Event.ENTER_FRAME,  renderScene);</pre>
<p>&#8230;and  add this method at the end of the class</p>
<pre>private  function renderScene(evt:Event):void
{
     camera.x = 3*(mouseX - stage.stageWidth/2);
     camera.y = 3*(mouseY -  stage.stageHeight/2);
     camera.lookAt(new Number3D(0, 0, 0));

     view.render();
}</pre>
<p>We’ve  just indicated that after initializing the scene, and then the objects in it, the  application should call the “renderScene()” method on enterframe, that is every  frame of course.</p>
<p>In  “renderScene()”, we will position the camera according to the position of the  mouse over the stage, and of course, render the view.</p>
<p>The  render() method of a View3D object is what calls all the 3d transformation  algorithms of the away3d engine and show us the display output in a view Sprite.</p>
<p>Now  compile… and voila!! That’s it.</p>
<p>Final words.</p>
<p>Pretty  nice huh? If you like it, there are some obvious steps you can take from here.  You can look on the <a title="Away3D Blog" href="http://away3d.com/" onclick="javascript:pageTracker._trackPageview('oclicks/http://away3d.com/');" target="_blank">Away3d Blog</a> for lots of info, samples and</p>
<p>Tutorials,  or you could sign up to the mailing list to see a vivid community learning and  expanding the away3d.Away3d can do pretty advanced stuff, specially when you  are ready to play with materials on your objects, or importing 3d models from  external programs. Ill  be writing more tutorials about this when I can.</p>
<p>Hope  its helpful…</p>
<p>Enjoy!</p>
<h3>Complete Code</h3>
<p><strong>Away3dProject.as</strong></p>
<pre>package
{
     import flash.display.Sprite;
     import flash.display.StageScaleMode;
     import flash.display.StageAlign;

     publicclass Away3dProject extends Sprite
     {
           publicfunction Away3dProject()
           {
                stage.scaleMode =  StageScaleMode.NO_SCALE;
                stage.align =  StageAlign.TOP_LEFT;

                var scene:Away3dScene = new Away3dScene();
                addChild(scene);
           }
     }
}</pre>
<p><strong>Away3dScene.as</strong></p>
<pre>package
{
     import away3d.cameras.Camera3D;
     import away3d.containers.Scene3D;
     import away3d.containers.View3D;
     import away3d.core.math.Number3D;
     import away3d.core.render.RectangleClipping;
     import away3d.primitives.Cube;

     import flash.display.Sprite;
     import flash.events.Event;

     publicclass Away3dScene extends Sprite
     {
           privatevar scene:Scene3D;
           privatevar camera:Camera3D;
           privatevar view:View3D;

           publicfunction Away3dScene()
           {
                addEventListener(Event.ADDED_TO_STAGE,  init, false, 0, true);
           }

           privatefunction init(evt:Event):void
           {
                removeEventListener(Event.ADDED_TO_STAGE,  init);

                init3dScene();
                init3dObjects();
                addEventListener(Event.ENTER_FRAME,  renderScene);
           }

           privatefunction init3dScene():void
           {
                scene = new Scene3D();

                camera = new Camera3D();
                camera.zoom = 10;
                camera.focus = 200;
                camera.z = -3000;
                camera.lookAt(new Number3D(0, 0, 0));

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

           privatefunction init3dObjects():void
           {
                var i:uint;
                var j:uint;
                var k:uint;
                var spacing:Number = 250;
                var quantity:uint = 3;
                var offset:Number = (quantity-1)*spacing/2;
                for(i = 0; i&lt;quantity; i++)
                {
                     for(j = 0; j&lt;quantity; j++)
                     {
                           for(k = 0; k&lt;quantity; k++)
                           {
                                var cube:Cube = new Cube();
                                cube.x  = i*spacing - offset;
                                cube.y  = j*spacing - offset;
                                cube.z  = k*spacing - offset;
                                scene.addChild(cube);
                           }
                     }
                }
           }

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

                view.render();
           }
     }
}</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=Setting%20up%20Away3d%20with%20Flex&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsetting-up-away3d-with-flex%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=Setting%20up%20Away3d%20with%20Flex&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2F3d%2Fsetting-up-away3d-with-flex%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_flex/~4/0nfazOb2w54" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thetechlabs.com/3d/setting-up-away3d-with-flex/</feedburner:origLink></item>
		<item>
		<title>Create a Flickr Viewer using Flex</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_flex/~3/TJalTHXg6Dg/</link>
		<comments>http://www.thetechlabs.com/interfaces/create-a-flickr-viewer-using-flex/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 23:06:20 +0000</pubDate>
		<dc:creator>Stéphane Schittly</dc:creator>
		
		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[adobe]]></category>

		<category><![CDATA[API]]></category>

		<category><![CDATA[Application]]></category>

		<category><![CDATA[Flickr]]></category>

		<category><![CDATA[how-to]]></category>

		<category><![CDATA[mxml]]></category>

		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=36</guid>
		<description><![CDATA[<p>In this tutorial, you will learn how to integrate photos from Flickr in your Flex application, using as3flickrlib.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/flex/">Flex</a> by Stéphane Schittly <a href="http://www.thetechlabs.com/interfaces/create-a-flickr-viewer-using-flex/#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>In this tutorial, you will learn how to integrate photos from Flickr in your Flex application, using as3flickrlib.</p>
<p>You will need a <a href="http://www.flickr.com/services/api/misc.api_keys.html" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.flickr.com/services/api/misc.api_keys.html');">Flickr API KEY</a> , <a hreflang="en" href="http://labs.adobe.com/technologies/flex/flexbuilder3/" onclick="javascript:pageTracker._trackPageview('oclicks/http://labs.adobe.com/technologies/flex/flexbuilder3/');">Adobe Flex Builder 3</a> or Eclipse with Flex Builder 3 plugin, and some basic knowledge of Flex and actionscript.</p>
<p>You can view the final application <a title="View Demo" href="http://blog.st-f.net/public/files/FlickrTutorial/FlickrViewer.html" onclick="javascript:pageTracker._trackPageview('oclicks/http://blog.st-f.net/public/files/FlickrTutorial/FlickrViewer.html');" target="_blank">here</a> (View Source is enabled).</p>
<p>All the source files are <a title="Download Source Files" href="http://www.thetechlabs.com/tutorials/files/FlickrViewer/FlickrViewer.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/FlickrViewer/FlickrViewer.zip');" target="_blank">here</a> .</p>
<h3>Part 1 : Creating the Flex project.</h3>
<p>Create  a new Flex project called &#8216;FlickrViewer&#8217;, and choose &#8216;Web application&#8217;.  Click on &#8216;Next&#8217;. Then, leave the output folder as default, it should be  &#8216;bin&#8217;. Click on &#8216;Next&#8217;.</p>
<h3>Part 2 : Design the user interface.</h3>
<p>The project is now ready to go. We will first designing the application.</p>
<p>Open  &#8216;FlexViewer.mxml&#8217;. Go to the Design Mode. Click on the application (it  should be a blue square taking all the page) and go the Properties  panel. Go to Layout and choose vertical in the comboBox. Then go to  Components panel, and in &#8216;Layout&#8217; select the ApplicationControlBar,  then drag it in the Application. Go to Flex Properties and set a width  of 100% and remove everything in height (the height of the  ApplicationControlBar will be the height of its contents).</p>
<p><img style="border: 0pt none; vertical-align: top; margin-top: 10px; margin-bottom: 10px;" src="http://www.thetechlabs.com/tutorials/files/FlickrViewer/designingApplication.jpg" alt="Designing Application" width="500" height="452" /></p>
<p>Drag  a &#8216;TextInput&#8217; component in the ApplicationControlBar and a &#8216;Button&#8217;  component just after the TextInput. Set the label of the button to  &#8216;SEARCH FLICKR&#8217;, in the Flex Properties panel. Add a TileList component  next of the ApplicationControlbar. Your application should look like  that :</p>
<p><img style="border: 0pt none; margin-top: 10px; margin-bottom: 10px;" src="http://www.thetechlabs.com/tutorials/files/FlickrViewer/ApplicationDesigned.jpg" alt="Application Designed" width="500" height="452" /></p>
<p>Now  set up the ID parameter of the TextInput, Button and TileList  components in the Flex Properties panel. TextInput should be set up to  &#8216;txtSearch&#8217;, the Button should be set up to &#8216;btnSearch&#8217; and the  TileList to &#8216;picsList&#8217;.</p>
<p>The user interface is completelly designed, let&#8217;s add Flickr.</p>
<h3>Part 3 : The libs.</h3>
<p>First, you will have to download the compiled versions of 2 libraries :</p>
<p>as3FlickrLib and asCoreLib. Go to</p>
<p><a href="http://code.google.com/p/as3flickrlib/" onclick="javascript:pageTracker._trackPageview('oclicks/http://code.google.com/p/as3flickrlib/');">http://code.google.com/p/as3flickrlib/</a> to get the first lib. Download</p>
<p>the package (featured downloads). Unzip the file, and the in the</p>
<p>expanded folder, go to bin/ and drag the file in Flex, inside your</p>
<p>project, in the src folder. Once it&#8217;s done, go to</p>
<p><a href="http://code.google.com/p/as3corelib/" onclick="javascript:pageTracker._trackPageview('oclicks/http://code.google.com/p/as3corelib/');">http://code.google.com/p/as3corelib/</a> and repeat the operation. You</p>
<p>should see that in your project : and some other files of course.</p>
<p><img style="border: 0pt none; vertical-align: top; margin-top: 10px; margin-bottom: 10px;" src="http://www.thetechlabs.com/tutorials/files/FlickrViewer/Image_1.png" alt="Fig 3" width="159" height="111" /><br />
So  now your project has the 2 libs.I strongly recommands you to use that  method in any projects. By doing that, you are sure that you always  have a working library. If you want to make a big application using  external libraries (which may evolve), I recommand you to use Flex  Library projects and SVN synchronization, it will allow you to keep  your code up to date.</p>
<p>To complete that part, you need to tell  Flex that you will use those libs. Right-click on the project name, and  then go to &#8216;properties&#8217; -&gt; &#8216;Flex Build Path&#8217; and then -&gt; &#8216;Library  path&#8217; and the &#8216;add SWC&#8217;. Choose corelib.swc and do the same for  flickr.swc.</p>
<h3>Part 4 : The code.</h3>
<p>In Code Mode, add a line after the   tag. Start typing &#8220;&lt;&gt; Mx:Script&#8217;. Press the Enter key. Now you  should have a complete script tag. Inside of this Script tag, include  the flickr functions we need :</p>
<pre>import com.adobe.webapis.flickr.*;
import com.adobe.webapis.flickr.events.*;</pre>
<p>Then, some variables :</p>
<pre>private var flickr:FlickrService;
private var api_key:String = "enter you Flickr API key here";
private var maxResult:Number = 50;</pre>
<p>After that, security parameters :</p>
<pre>Security.allowDomain(["api.flickr.com", "flickr.com", "*"]);
Security.allowInsecureDomain(["api.flickr.com", "flickr.com", "*"]);</pre>
<p>And set the dataProvider of the TileList :</p>
<pre>import mx.collections.ArrayCollection;
[Bindable] public var photos:ArrayCollection;</pre>
<p>&#8216;Bindable&#8217; means that the TileList will update each time the dataProvider change.</p>
<p>After  that the function to call Flickr webservice. Basically, that means that  we set up the api_key to send, an eventListener to know when the data  comes back, and the request itself to search photos, based on the  TextInput value.</p>
<pre>private function getImages():void {
var service:FlickrService = new FlickrService( api_key );
service.addEventListener( FlickrResultEvent.PHOTOS_SEARCH, onPhotosSearch );
service.photos.search("", txtSearch.text, "any", "", null, null, null, null, null, "", maxResult,1 );
}</pre>
<p>Now  that the code is done, we just need to connect the TileList to the  data. Go to the TileList tag, and at the end of the parameters, just  add &#8216;dataProvider={photos}&#8217;. The tag should now look like that :</p>
<pre>&lt;mx:TileList width="100%" height="100%" id="picsList" dataProvider="{photos}" itemRenderer="iconRenderer" &gt;</pre>
<p>If you run the application now, you wont see any images. It&#8217;s because we miss an itemRenderer for the image.</p>
<h3>Part 5 : The necessary itemRenderer</h3>
<p>Go  to &#8216;File&#8217; -&gt; &#8216;New&#8217; -&gt; &#8216;MXML Component&#8217;. Type &#8216;iconRenderer&#8217; as  filename and choose &#8216;Box&#8217; in &#8216;Based on&#8217;. Remove width and height.</p>
<p>Go to Design Mode. Drop an Image Component. In the Flex Properties panel, set the ID to &#8216;pic&#8217;.</p>
<p>Go to Code Mode. Add a script tag after the first Tag. In this script tag, add the following lines :</p>
<pre>import com.adobe.webapis.flickr.Photo;
import mx.core.Application;
public function init():void{
pic.source = 'http://static.flickr.com/' + data.server + '/' + data.id + '_' + data.secret + '_m.jpg';
//trace("source : "+pic.source)
}</pre>
<p>Then, add an updateComplete event listener to this init function in the Box tag. It should look like that :</p>
<p>The itemRenderer is not ready. The complete code should be this :</p>
<h3>Part 6 : Linking the itemRenderer to TileList</h3>
<p>Go back to FlickrViewer.mxml. In Code Mode, go to the TileList tag and add the itemRenderer parameter by typing :</p>
<p>itemRenderer=&#8221;iconRenderer&#8221;</p>
<p>The complete code for FlickViewer is done and should look like this :</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
//import mx.messaging.channels.StreamingAMFChannel;
import com.adobe.webapis.flickr.*;
import com.adobe.webapis.flickr.events.*;
private var flickr:FlickrService;
private var api_key:String = "enter you Flickr API key here";
private var maxResult:Number = 50;
private var service:FlickrService = new FlickrService( api_key );

Security.allowDomain(["api.flickr.com", "flickr.com", "*"]);
Security.allowInsecureDomain(["api.flickr.com", "flickr.com", "*"]);

import mx.collections.ArrayCollection;
[Bindable] public var photos:ArrayCollection;

private function getImages():void {
  var service:FlickrService = new FlickrService( api_key );
  service.addEventListener( FlickrResultEvent.PHOTOS_SEARCH, onPhotosSearch );
  service.photos.search(&#8221;", txtSearch.text, &#8220;any&#8221;, &#8220;&#8221;, null, null, null, null, null, &#8220;&#8221;, maxResult,1 );
}

private function onPhotosSearch( event:FlickrResultEvent ):void {
  var photoList:PagedPhotoList = event.data.photos;
  photoList.perPage = maxResult;
  photos = new ArrayCollection( photoList.photos );
}
]]&gt;
&lt;/mx:Script&gt;
&lt;mx:ApplicationControlBar width=&#8221;100%&#8221;&gt;
&lt;mx:TextInput id=&#8221;txtSearch&#8221;/&gt;
&lt;mx:Button label=&#8221;SEARCH ON FLICKR&#8221; id=&#8221;btnSearch&#8221; click=&#8221;getImages()&#8221;/&gt;
&lt;/mx:ApplicationControlBar&gt;
&lt;mx:TileList width=&#8221;100%&#8221; height=&#8221;100%&#8221; id=&#8221;picsList&#8221; dataProvider=&#8221;{photos}&#8221; itemRenderer=&#8221;iconRenderer&#8221; &gt;
&lt;/mx:TileList&gt;
&lt;/mx:Application&gt;</pre>
<p>And the final code for iconRenderer.mxml :</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" updateComplete="init()"&gt;
&lt;mx:Script&gt;
&lt;![CDATA[
import com.adobe.webapis.flickr.Photo;
import mx.core.Application;
public function init():void{
pic.source = 'http://static.flickr.com/' + data.server + '/' + data.id + '_' + data.secret + '_m.jpg';
//trace("source : "+pic.source)
}
]]&gt;
&lt;/mx:Script&gt;
&lt;mx:Image id=&#8221;pic&#8221; width=&#8221;100&#8243; height=&#8221;100&#8243; /&gt;
&lt;/mx:Box&gt;</pre>
<h3>Part 7 : click to enlarge</h3>
<p>Now the users can watch a list of pictures. That&#8217;s ok but not very good.</p>
<p>To  allow users to enlarge the pics, we will first create a new component,  wich will contain the big pic. Go to File &gt; New &gt; MXML Component.  Enter &#8216;bigPic.mxml&#8217; as filename and &#8216;TitleWindow&#8217; in &#8216;based on&#8217;. Enter  &#8216;100%&#8217; for both width and height. Now, change the first tag by this one  :</p>
<pre>&lt;mx:TitleWindow xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:controls="qs.controls.*" xmlns:smooth="imageControls.*"
    xmlns:eff="com.adobe.effects.*" xmlns:views="views.*"
    layout="vertical"
    height="100%" width="100%"
    title="CLICK ANYWHERE TO CLOSE" textAlign="center" color="#333333"
    backgroundColor="#000000" backgroundAlpha="0.9"
    borderThicknessLeft="0" borderThicknessRight="0" borderThicknessTop="0" borderThicknessBottom="0"
    headerHeight="25" verticalScrollPolicy="off" horizontalScrollPolicy="off"
    paddingBottom="0" paddingLeft="0" paddingRight="0" paddingTop="0"
    creationComplete="init()"&gt;</pre>
<p>The  &#8216;xmlns&#8217;  are references to libs we will use. There are some graphical  stuff, like borderThickness, you can read Flex Documentations to know  more, they are basically use to fit the browser&#8217;s window.</p>
<p>Go  back to FlickViewer.mxml. To launch this component when the user clicks  on an item in the list, add this code in the Script tag, at the end :</p>
<pre>///// BIGPIC FUNCTIONS
            import mx.managers.PopUpManager;
            import mx.containers.TitleWindow;
            import bigPic;
            import mx.events.FlexMouseEvent;
            import mx.core.Application;

            public var fullWindow:bigPic;

            public function showBigPic(id:String):void {
                fullWindow = bigPic(PopUpManager.createPopUp(this, bigPic, true));
                fullWindow.selectedPhoto = id;
                fullWindow.selectedPhotoNum = picsList.selectedIndex;
            }</pre>
<p>Then look in the mxml code, and find the TileList tag. in the tag, add the itemClick property to launch the big pic :</p>
<p>itemClick=&#8221;showBigPic(event.itemRenderer.data.id)&#8221;</p>
<p>The tag should now look like that :</p>
<pre>&lt;mx:TileList width="100%" height="100%" id="picsList"
        dataProvider="{photos}" itemRenderer="iconRenderer"
        itemClick="showBigPic(event.itemRenderer.data.id)" &gt;</pre>
<p>Now, let&#8217;s add some layout. Go back to bigPic.mxml, and between the two tags on the stage, add this code :</p>
<pre>&lt;mx:Canvas height="100%" width="100%"&gt;
        &lt;mx:Canvas x="0" y="0" id="preload" width="100%" height="100%" click="removeMe()" &gt;
                &lt;mx:Box width="100%" height="100%" verticalAlign="middle"&gt;
                    &lt;mx:ProgressBar id="preloadBar" source="daPic" mode="event" width="100%"
                        complete="preload.visible = false; img.visible = true;" labelPlacement="bottom"/&gt;
                        &lt;mx:Label id="imgTitle" width="100%" textAlign="center"
                            text="{Application.application.photos.getItemAt(Application.application.selectedPhotoNum).title}"
                            fontSize="25" color="#666666" /&gt;
                    &lt;mx:Image id="daPic2" source="{photoUrl}" visible="false" width="1" height="1" /&gt;
                &lt;/mx:Box&gt;
        &lt;/mx:Canvas&gt;
        &lt;mx:Canvas x="0" y="0" width="100%" height="100%" id="img"
            showEffect="{fadeAndBlurIn}" hideEffect="{fadeAndBlurOut}"
            verticalScrollPolicy="off" horizontalScrollPolicy="off"&gt;
            &lt;mx:HBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle"&gt;
                &lt;mx:Box id="prevBox" visible="true" width="100" height="100%" horizontalAlign="center"&gt;
                    &lt;mx:Spacer height="50%" /&gt;
                    &lt;mx:Button width="70" label="prev" click="changePic('prev')" /&gt;
                &lt;/mx:Box&gt;
                &lt;mx:Box width="100%" height="100%"
                    verticalAlign="middle" horizontalAlign="center" click="removeMe()"&gt;
                    &lt;mx:Image id="daPic" source="{photoUrl}"
                        verticalAlign="center" horizontalAlign="middle"
                        width="100%" height="100%" cacheAsBitmap="true"  /&gt;
                &lt;/mx:Box&gt;
                &lt;mx:Box id="nextBox" width="100" height="100%" bottom="10%" horizontalAlign="center"&gt;
                    &lt;mx:Spacer height="50%" /&gt;
                    &lt;mx:Button width="70" label="next" click="changePic('next')" /&gt;
                &lt;/mx:Box&gt;
            &lt;/mx:HBox&gt;
        &lt;/mx:Canvas&gt;
    &lt;/mx:Canvas&gt;</pre>
<p>It&#8217;s  a canvas containing 2 Canvases. The first one contains a ProgressBar,  which will show image loading progression. The &#8216;onComplete&#8217; event in  the tag set this canvas to invisible at the end of the loading. By  being invisible, we will be able to see the second Canvas, which  contains the image.</p>
<p>Inside the second Canvas, you can see 3  Boxes. The first one contains a Button, the next one the image, and the  third one another Button. That&#8217;s how your application will look like :  a big pic surrounded by two navigation buttons. We will see the code in  part 9.</p>
<p>There is in each Canvas a &#8217;showEffect&#8217; and &#8216;hideEffect&#8217;  parameter. It&#8217;s made to make a nice fade between the preloader and the  photo. But the effects are not here. We will add them right now.</p>
<h3>Part 8 : Adding fade effect</h3>
<p>Add the following code just after the first tag (<em>TitleWindow</em> ) :</p>
<pre>&lt;mx:Sequence id="fadeAndBlurIn" startDelay="0" &gt;
        &lt;mx:Fade id="fadeIn" duration="1200" alphaFrom="0.0" alphaTo="1.0" /&gt;
    &lt;/mx:Sequence&gt;
    &lt;mx:Sequence id="fadeAndBlurOut" startDelay="0"&gt;
        &lt;mx:Fade id="fadeOut" duration="300" alphaFrom="1.0" alphaTo="0" /&gt;
    &lt;/mx:Sequence&gt;</pre>
<p>All effect needs to be set after the first tag, and it&#8217;s mandatory, as well as for Scripts and Style tags.</p>
<h3>Part 9 : Adding code to load the big pic, and manage the navigation</h3>
<p>After the first tag, add this code :</p>
<pre>&lt;mx:Script&gt;
        &lt;![CDATA[
            import mx.core.Application;
            import mx.rpc.soap.LoadEvent;
            import mx.managers.SystemManager;
            import mx.managers.PopUpManager;
            import mx.utils.ArrayUtil;
            import mx.collections.ArrayCollection;

            import com.adobe.webapis.flickr.methodgroups.People;
            import com.adobe.webapis.flickr.methodgroups.PhotoSets;
            import com.adobe.webapis.flickr.FlickrService;
            import com.adobe.webapis.flickr.*;
            import com.adobe.webapis.flickr.events.*;

            [Bindable] private var photos:ArrayCollection;
            [Bindable] private var photoUrl:String;
            [Bindable] private var photoFlickrUrl:String;
            [Bindable] public var selectedPhotoNum:Number;
            [Bindable] public var selectedPhoto:String;

            public function init():void
            {
                img.visible = false;
                this.width = stage.width;
                this.height = stage.height;
                getPhotoSize();
            }

            private function removeMe():void {
                PopUpManager.removePopUp(this);
            }

            private function getPhotoSize():void{
                trace(&#8221;getPhotoSize: &#8220;+selectedPhoto)
                preload.visible = true
                img.visible = false;
                var service:FlickrService = new FlickrService( Application.application.api_key );
                   service.addEventListener( FlickrResultEvent.PHOTOS_GET_SIZES, onPhotoSizeSearch );
                   service.photos.getSizes( Application.application.photos[selectedPhotoNum].id );
            }

            private function onPhotoSizeSearch( event:FlickrResultEvent ):void {
                var photoSize:PhotoSize = event.data["photoSizes"] as PhotoSize;
                imgTitle.text = Application.application.photos[selectedPhotoNum].title
                var result:Array = event.data.photoSize;
                photoUrl = event.data["photoSizes"][(event.data["photoSizes"].length-1)].source;
            } 

            public function changePic(operation:String):void{
                if(operation == &#8220;next&#8221;){
                    if(selectedPhotoNum &lt; Application.application.photos.length-1){
                        selectedPhotoNum++;
                    }else{
                        selectedPhotoNum = 0;
                    }
                }else{
                    if(selectedPhotoNum &gt; 0){
                        selectedPhotoNum&#8211;;
                    }else{
                        selectedPhotoNum = Application.application.photos.length-1;
                    }
                }
                getPhotoSize();
            }

        ]]&gt;
    &lt;/mx:Script&gt;</pre>
<p>It sure looks quite long, but it&#8217;s really simple.</p>
<p><strong>The init() function </strong> react  to the &#8216;OnCreationComplete&#8217; event in the first tag. The first line hide  the &#8216;img&#8217; canvas, so we dont see it during the loading. The two second  lines simply fit the component to the browser window, and the last line  launch the loading of the first image.</p>
<p><strong>The getPhotoSize()</strong> function is the core of this component. It will search all the available sizes for the image.</p>
<p><strong>The onPhotoSizeSearch()</strong> function is executed when the getPhotoSize() is done. The aim of this  function is to set the text for the label in the preloader canvas, and  - most important - get the URL of the biggest image available. It&#8217;s  this line :</p>
<pre>photoUrl = event.data["photoSizes"][(event.data["photoSizes"].length-1)].source;</pre>
<p>&#8216;photoSizes&#8217; is an array retured by Flickr, which define the sizes from the smallest to the biggest.</p>
<p>And finally, <strong>the changePic()</strong> function simply handle the navigation. If you look closely in the mxml  code, you will see two buttons. When clicked, this function is called  and just add or remove 1 to selectedPhotoNum, a variable that  getPhotoSize() use to know which image to load. Of course, we add some  conditions to prevent errors due to undefined id (because if it  happens, the application will sure crash :-)).</p>
<h3>Part 10 : Launch your application and enjoy !</h3>
<p>Click  on the run application button, and in the browser, type a word in the  search box. Normally, you should see images appearing. If you see them,  you just manage to make your first Flickr / Flex mashup. Congrats !</p>
<p>Now, look further : you can do a lot with that. Flickr has a whole range of functions that you can discover <a hreflang="en" href="http://www.flickr.com/services/api/" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.flickr.com/services/api/');">here</a> . You can also refer to the <a hreflang="en" href="http://as3flickrlib.googlecode.com/svn/trunk/docs/index.html" onclick="javascript:pageTracker._trackPageview('oclicks/http://as3flickrlib.googlecode.com/svn/trunk/docs/index.html');">asflickrlib docs on google code</a> . You can do almost everything that users do on the Flickr website.</p>
<p>Plus,  you can add more effects, or even do crazy stuff with papervision,  physics engines&#8230; The possiblities are unlimited. All you need to find  now is the revolutionnary idea to do something with all those pictures  !</p>
<p>You only need to consider one limitation : Flickr can be  slow. And by doing that, you can&#8217;t really manage the speed of your  application. So avoid to load too much photos on each request. Use the  max_result parameter to limit this amount.</p>
<p>This concludes my  first tutorial. Thank for reading that to the end. I hope that you  enjoy reading it and that it will help you. To thank me, just drop a  line in the comments, make a link on your website or, even better, send  me a picture of you drinking a beer in your local pub <img src='http://www.thetechlabs.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></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=Create%20a%20Flickr%20Viewer%20using%20Flex&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Finterfaces%2Fcreate-a-flickr-viewer-using-flex%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=Create%20a%20Flickr%20Viewer%20using%20Flex&amp;linkurl=http%3A%2F%2Fwww.thetechlabs.com%2Finterfaces%2Fcreate-a-flickr-viewer-using-flex%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_flex/~4/TJalTHXg6Dg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.thetechlabs.com/interfaces/create-a-flickr-viewer-using-flex/feed/</wfw:commentRss>
		<feedburner:origLink>http://www.thetechlabs.com/interfaces/create-a-flickr-viewer-using-flex/</feedburner:origLink></item>
		<item>
		<title>Creating A Downloader For YouTube with Flex/Air</title>
		<link>http://feedproxy.google.com/~r/TheTechLabs_flex/~3/ESHudCfZYhQ/</link>
		<comments>http://www.thetechlabs.com/video/creating-a-downloader-for-youtube-with-flexair-2/#comments</comments>
		<pubDate>Thu, 12 Jun 2008 10:58:17 +0000</pubDate>
		<dc:creator>Jack Herrington</dc:creator>
		
		<category><![CDATA[AIR]]></category>

		<category><![CDATA[Flex]]></category>

		<category><![CDATA[Interfaces]]></category>

		<category><![CDATA[Video]]></category>

		<category><![CDATA[adobe air]]></category>

		<category><![CDATA[adobe flex]]></category>

		<category><![CDATA[how-to]]></category>

		<category><![CDATA[tutorial]]></category>

		<category><![CDATA[YouTube]]></category>

		<guid isPermaLink="false">http://www.thetechlabs.com/?p=61</guid>
		<description><![CDATA[<p>YouTube’s mixed easy movie access with community uploads to create a startling new service. The online problem is that you can only access YouTube when you are online. How can you access those movies when you are offline? Let’s solve that problem by building a downloader with Flex and AIR.<br />
In this article we will build a cross platform application that searches for YouTube videos and then provides a mechanism to download those videos and view them locally. You will be able to take your favorite YouTube videos with you wherever you go.</p>
<small><em>posted in <a href="http://www.thetechlabs.com/category/air/">AIR</a> by Jack Herrington <a href="http://www.thetechlabs.com/video/creating-a-downloader-for-youtube-with-flexair-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>YouTube’s mixed easy movie access with community uploads to create a startling new service. The online problem is that you can only access YouTube when you are online. How can you access those movies when you are offline? Let’s solve that problem by building a downloader with Flex and AIR.<br />
In this article we will build a cross platform application that searches for YouTube videos and then provides a mechanism to download those videos and view them locally. You will be able to take your favorite YouTube videos with you wherever you go.</p>
<h3>Requirements</h3>
<p><strong>Flex 3</strong> <a title="Try/Buy" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank"></a></p>
<p><a title="Try/Buy" href="http://www.adobe.com/products/flex/?promoid=BPDEQ" onclick="javascript:pageTracker._trackPageview('oclicks/http://www.adobe.com/products/flex/?promoid=BPDEQ');" target="_blank">Try/Buy</a></p>
<p><strong>Sample files:</strong></p>
<p><a title="Download Sample Files" href="http://thetechlabs.com/tutorials/files/youtube/YouTube.zip" onclick="javascript:pageTracker._trackPageview('downloads/tutorials/files/youtube/YouTube.zip');">YouTube.zip</a><br />
Let’s start by building the search user interface.</p>
<h3>Searching YouTube</h3>
<p>YouTube provides a set of RSS feeds that keep you up to date with the latest videos. These feeds take lots of parameters to refine what you are looking for, one of those is an arbitrary keyword search.<br />
The Flex code below uses the YouTube search feed to request a set of videos based on the user’s search criteria. The code then uses the e4x language extensions in ActionScript 3 to parse the feed and present the video thumbnails in a TileList.</p>
<pre>&lt;?xml version="1.0" encoding="utf-8"?&gt; 

  &lt;mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"  title="YouTube  Search"&gt; 

  &lt;mx:Script&gt; 

  &lt;![CDATA[ 

  <strong>import</strong>
 mx.rpc.events.ResultEvent; 

  <strong>import</strong>
 mx.rpc.http.HTTPService; 

<strong>namespace</strong>
 atom = <strong>"http://www.w3.org/2005/Atom"</strong>
; 

    <strong>namespace</strong>
 media = <strong>"http://search.yahoo.com/mrss/"</strong>
; 

<strong>private</strong>
 <strong>function</strong>
 onSearch() : <strong>void</strong>
 { 

    <strong>var</strong>
 search:HTTPService = <strong>new</strong>
 HTTPService(); 

    search.url = <strong>"http://gdata.youtube.com/feeds/api/videos/?vq="</strong>
+escape(txtSearch.text)+<strong>"&amp;orderby=updated"</strong>
; 

    search.resultFormat = <strong>'e4x'</strong>
; 

     search.addEventListener(ResultEvent.RESULT,onSearchResult); 

    search.send(); 

  } 

  <strong>private</strong>
 <strong>function</strong>
 onSearchResult( event:ResultEvent ) : <strong>void</strong>
 { 

    <strong>use</strong>
 <strong>namespace</strong>
 atom; 

    <strong>use</strong>
 <strong>namespace</strong>
 media; 

    <strong>var</strong>
 movies:Array = []; 

    <strong>for</strong>
 <strong>each</strong>
( <strong>var</strong>
 entry:XML <strong>in</strong>
 event.result..entry ) { 

      <strong>var</strong>
 group:XML = entry.group[0]; 

      movies.push( { 

         id:group.player.@url.toString(), 

         description:entry.content.toString(), 

         thumbnail:group.thumbnail[0].@url.toString() } ); 

    } 

    thumbList.dataProvider =  movies; 

  } 

  ]]&gt; 

  &lt;/mx:Script&gt; 

  &lt;mx:HBox  width=&#8221;100%&#8221;&gt; 

  &lt;mx:TextInput  width=&#8221;100%&#8221; id=&#8221;txtSearch&#8221; /&gt; 

  &lt;mx:Button  label=&#8221;Search&#8221; click=&#8221;onSearch()&#8221; /&gt; 

  &lt;/mx:HBox&gt; 

  &lt;mx:TileList  id=&#8221;thumbList&#8221; width=&#8221;100%&#8221; height=&#8221;100%&#8221;&gt; 

  &lt;mx:itemRenderer&gt; 

  &lt;mx:Component&gt; 

  &lt;mx:HBox  paddingBottom=&#8221;5&#8243; paddingLeft=&#8221;5&#8243; paddingRight=&#8221;5&#8243;  paddingTop=&#8221;5&#8243;&gt; 

  &lt;mx:Image  source =&#8221;{data.thumbnail}&#8221; height=&#8221;100&#8243; width=&#8221;150&#8243; horizontalAlign=&#8221;center&#8221; verticalAlign=&#8221;middle&#8221; toolTip=&#8221;{data.description}&#8221;&gt; 

  &lt;/mx:Image&gt; 

  &lt;/mx:HBox&gt; 

  &lt;/mx:Component&gt; 

  &lt;/mx:itemRenderer&gt; 

  &lt;/mx:TileList&gt; 

  &lt;/mx:WindowedApplication&gt;</pre>
<p>The onSearch method is called from the search button. It creates a new HTTPService on the fly with the URL of the YouTube feed for the search. It then registers onSearchResult as an event handler for the result.<br />
The onSearchResult method uses e4x to parse through each ‘entry’ tag in the RSS feed. For each movie it builds an object with three fields. The ‘id’ field holds the URL of the HTML page for the video. The ‘description’ field holds the textual description of the video. And the ‘thumbnail’ field holds the URL of the thumbnail.<br />
When I launch this MXML in an AIR project within Flex Builder 3 I see something like Figure 1.</p>
<p align="center"><img src="http://thetechlabs.com/wp-content/uploads/2008/06/fig1.png" border="0" alt="Figure 1-1. Just the YouTube search" width="540" height="380" /></p>
<p align="center"><strong>Figure 1-1. Just the YouTube search</strong></p>
<p>In this case I’ve typed in ‘super mario’ and pressed ‘search’ to get a list of the movies that matched that criteria.<br />
From here we ne