Recipe 6.6. Loading External Images at Runtime


Problem

You want to load an external image into a movie while it plays.

Solution

Use the new Loader class to load an image (.jpg, progressive .jpg, .png, or .gif) and display it on-screen.

Discussion

Recipe 9.17 demonstrates how to embed external assets into a movie at compile time via the [Embed] metadata tag. To load external images or movies at runtime during the playback of a .swf, the Loader class needs to be used.

The flash.display.Loader class is very similar to the flash.net.URLLoader class discussed in Recipe 19.3. One of the key differences is that Loader instances are able to load external images and movies and display them on-screen, whereas URLLoader instances are useful for transferring data.

There are three fundamental steps for loading external content:

  1. Create an instance of the Loader class.

  2. Add the Loader instance to the display list.

  3. Call the load( ) method to pull in an external asset.

The load( ) method of the Loader class is responsible for downloading the image or .swf file. It takes a single URLRequest object as a parameter that specifies the URL of the asset to download and display.

The following is a small example of using a Loader instance to download an image named image.jpg at runtime. The code in the LoaderExample constructor has been commented to coincide with the three basic loading steps previously outlined:

package {   import flash.display.*;   import flash.net.URLRequest;   public class LoaderExample extends Sprite {     public function LoaderExample(  ) {       // 1. Create an instance of the Loader class       var loader:Loader = new Loader(  );       // 2. Add the Loader instance to the display list       addChild( loader );       // 3. Call the load(  ) method to pull in an external asset       loader.load( new URLRequest( "image.jpg" ) );     }   } }

When running this code, the Flash Player looks for image.jpg in the same directory that the .swf movie is being served from because the URLRequest object uses a relative URL. Either a relative or absolute URL can be used to point to the location of the target to load, but the actual loading of the asset is governed by Flash Player's security sandbox, as discussed in Recipe 3.12. As soon as the asset has downloaded, it is automatically added as a child of the Loader instance.

When loading external assets, it's possible that something could go wrong during the loading process. For instance, perhaps the URL is pointing to the incorrect location due to a spelling mistake, or there's a security sandbox violation that won't allow the asset to be loaded. Or, it's possible that the asset is large and is going to take a long time download. Rather than just having an empty screen while the asset downloads, you'd like to show a preloader to inform the user of the download progress.

In these situations, you should add event listeners to the contentLoaderInfo property of the Loader instance to be able to respond to the different events as they occur. The contentLoaderInfo property is an instance of the flash.display.LoaderInfo class, designed to provide information about the target being loaded. The following is a list of useful events dispatched by instances of the LoaderInfo class and what those events mean:


open

Generated when the asset has started downloading.


progress

Generated when progress has been made while downloading the asset.


complete

Generated when the asset has finished downloading.


init

Generated when the properties and methods of a loaded external .swf are available.


httpStatus

Generated when the status code for a failed HTTP request is detected when attempting to load the asset.


ioError

Generated when a fatal error occurs that results in an aborted download, such as not being able to find the asset.


securityError

Generated when data you're trying to load resides outside of the security sandbox.


unload

Generated when either the unload( ) method is called to remove the loaded content or the load( ) method is called again to replace content that already has been loaded.

The following example demonstrates listening for the various download progress related events when loading an image:

package {   import flash.display.*;   import flash.text.*;   import flash.net.URLRequest;   import flash.events.*;   public class LoaderExample extends Sprite {     public function LoaderExample(  ) {       // Create the loader and add it to the display list       var loader:Loader = new Loader(  );       addChild( loader );              // Add the event handlers to check for progress       loader.contentLoaderInfo.addEventListener( Event.OPEN, handleOpen );       loader.contentLoaderInfo.addEventListener( ProgressEvent.PROGRESS, handleProgress );       loader.contentLoaderInfo.addEventListener( Event.COMPLETE, handleComplete );              // Load in the external image       loader.load( new URLRequest( "image.jpg" ) );     }          private function handleOpen( event:Event ):void {       trace( "open" );     }          private function handleProgress( event:ProgressEvent ):void {       var percent:Number = event.bytesLoaded / event.bytesTotal * 100;       trace( "progress, percent = " + percent );     }          private function handleComplete( event:Event ):void {       trace( "complete" );     }   } }

When running the preceding code, you'll see the open message appear in the console window followed by one or more progress messages displaying the current percent loaded, followed by the complete message signaling that the download finished successfully.

By placing code in the event handlers for these events, you can show the progress of a download as it's being loaded. For instance, the handleOpen( ) method would be in charge of creating the preloader and adding it to the display list. The handleProgress( ) method would update the percentage value of the preloader, such as setting the text of a TextField instance to the percent value. Finally, the handleComplete( ) method would perform "clean up" and remove the preloader, since the asset is fully downloaded. Focusing on those methods, the code might look something like this:

private function handleOpen( event:Event ):void {   // Create a simple text-based preloader and add it to the    // display list   _loaderStatus = new TextField(  );   addChild( loaderStatus );   _loaderStatus.text = "Loading: 0%"; } private function handleProgress( event:ProgressEvent ):void {   // Update the loading % to inform the user of progress   var percent:Number = event.bytesLoaded / event.bytesTotal * 100;   _loaderStatus.text = "Loading: " + percent + "%"; } private function handleComplete( event:Event ):void {   // Clean up - preloader is no longer necessary   removeChild( loaderStatus );   _loaderStatus = null; }

The preceding code snippet assumes that there is a _loaderStatus variable as part of the class, with type TextField:

private var _loaderStatus:TextField;

Instead of messages appearing via the trace( ) statement as before, modifying the event handlers allows the loading information to be presented inside of the movie itself. This allows users to see the information directly and provides a better experience when loading large external assets.

See Also

Recipes 3.12, 6.7, 9.17, and 19.3




ActionScript 3. 0 Cookbook
ActionScript 3.0 Cookbook: Solutions for Flash Platform and Flex Application Developers
ISBN: 0596526954
EAN: 2147483647
Year: 2007
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net