Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ActionScript 2.0 2006

.pdf
Скачиваний:
101
Добавлен:
17.08.2013
Размер:
12.47 Mб
Скачать

Chapter 8

Here’s an example implementation that loads an external movie clip called section1.swf into a movie clip called sectionHolder:

this.createEmptyMovieClip(“sectionHolder”, this.getNextHighestDepth());

var loadListener:Object = new Object(); loadListener.onLoadComplete = function(contentHolder:MovieClip)

{

trace(“Content has been loaded”);

};

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“section1.swf”, sectionHolder);

removeListener()

The removeListener() method is used to break the binding between the event handlers and the pre-loader. It takes one parameter, which is the handle to the listener object that was initially passed in to the addListener() method. The following prototype shows the basic form of the removeListener() method:

loaderObject.removeListener(listener:Object) : Boolean

If, for example, you want to hold up playback until enough of the movie has downloaded to ensure that playback is not impeded by network delays, you could handle it like the following example, which removes the listener and starts playback after 50% of the movie has downloaded:

this.createEmptyMovieClip(“sectionHolder”, this.getNextHighestDepth());

var loadListener:Object = new Object(); loadListener.onLoadProgress = function(contentHolder:MovieClip, ;

bytesLoaded:Number, bytesTotal:Number)

{

var percentDone:Number = bytesLoaded / bytesTotal * 100; if (percentDone > 50)

{

contentHolder.play();

contentLoader.removeListener(this);

}

};

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“section1.swf”, sectionHolder);

unloadClip()

Media should be properly unloaded from the movie clip before another clip is loaded. The unloadClip() method takes one parameter, which is a handle to the movie clip containing the loaded media. The following prototype shows the basic form of the unloadClip() method:

loaderObject.unloadClip(target:Object) : Boolean

208

Pre-Loading Movies

The following example shows how you can unload a movie clip:

this.createEmptyMovieClip(“sectionHolder”, this.getNextHighestDepth());

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.loadClip(“section1.swf”, sectionHolder);

cancelButton.onRelease = function()

{

contentLoader.unloadClip(sectionHolder);

};

Implementing the MovieClipLoader Class

With an understanding of the MovieClipLoader class, you’re ready to put it into action. First, put together a shell for the event handlers and tie that in to a new loader instance:

this.createEmptyMovieClip(“sectionHolder”, this.getNextHighestDepth());

var loadListener:Object = new Object(); loadListener.onLoadStart = function(contentHolder:MovieClip)

{

};

loadListener.onLoadProgress = function(contentHolder:MovieClip, ; bytesLoaded:Number, bytesTotal:Number)

{

};

loadListener.onLoadComplete = function(contentHolder:MovieClip)

{

};

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“http://www.nathanderksen.com/book/trailer.swf”, ;

sectionHolder);

Here, an empty object is created, and one method is added for each event to be handled. Not all events have to be handled, just the ones that you need. A new instance of the loader class is created and is bound to this object. Finally, the clip is loaded into the container movie clip. At this point you have a working pre-loader; it just does not call anything yet before, during, or after loading.

Each of these code snippets is available in the downloadable content for this book. Feel free to experiment with each snippet.

Like the custom loader created previously, you still need to provide visual feedback for the user. Add the shell code for this:

this.createEmptyMovieClip(“sectionHolder”, this.getNextHighestDepth()); this.createEmptyMovieClip(“progressMovie”, this.getNextHighestDepth()); progressMovie._x = 60;

progressMovie._y = 120;

209

Chapter 8

progressMovie.createTextField(“percentDoneLabel”,

progressMovie.getNextHighestDepth(), 40, 0, 100, 20);

var loadListener:Object = new Object(); loadListener.onLoadStart = function(contentHolder:MovieClip)

{

};

loadListener.onLoadProgress = function(contentHolder:MovieClip, ; bytesLoaded:Number, bytesTotal:Number)

{

};

loadListener.onLoadComplete = function(contentHolder:MovieClip)

{

};

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“http://www.nathanderksen.com/book/trailer.swf”, ;

sectionHolder);

function showProgress(percentDone:Number, progressBarHolder:MovieClip) : Void

{

var barWidth:Number = percentDone;

progressBarHolder.percentDoneLabel.text = String(Math.ceil(percentDone))+” %”; progressBarHolder.clear();

//Draw a border progressBarHolder.moveTo(0, 20); progressBarHolder.lineStyle(1, 0x666666); progressBarHolder.lineTo(100, 20); progressBarHolder.lineTo(100, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20);

//Draw the bar progressBarHolder.moveTo(0, 20); progressBarHolder.beginFill(0xCCCCCC, 100); progressBarHolder.lineTo(barWidth, 20); progressBarHolder.lineTo(barWidth, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20); progressBarHolder.endFill();

}

As before, a movie clip holds the progress bar and the percent progress text field, and the showProgress() function draws the progress bar and updates the percent progress value.

Finally, you need to fill out the event handlers:

this.createEmptyMovieClip(“sectionHolder”, this.getNextHighestDepth()); this.createEmptyMovieClip(“progressMovie”, this.getNextHighestDepth()); progressMovie._x = 60;

210

Pre-Loading Movies

progressMovie._y = 120; progressMovie.createTextField(“percentDoneLabel”, progressMovie.getNextHighestDepth(), 40, 0, 100, 20);

var loadListener:Object = new Object(); loadListener.onLoadStart = function(contentHolder:MovieClip)

{

progressMovie._visible = true; contentHolder._visible = false; contentHolder.stop();

};

loadListener.onLoadProgress = function(contentHolder:MovieClip, ; bytesLoaded:Number, bytesTotal:Number)

{

var percentDone:Number = bytesLoaded / bytesTotal * 100;

showProgress(percentDone, progressMovie);

};

loadListener.onLoadComplete = function(contentHolder:MovieClip)

{

progressMovie._visible = false; contentHolder._visible = true; contentHolder.play();

};

var contentLoader:MovieClipLoader = new MovieClipLoader(); contentLoader.addListener(loadListener); contentLoader.loadClip(“http://www.nathanderksen.com/book/trailer.swf”, ;

sectionHolder);

function showProgress(percentDone:Number, progressBarHolder:MovieClip) : Void

{

var barWidth:Number = percentDone;

progressBarHolder.percentDoneLabel.text = String(Math.ceil(percentDone))+” %”; progressBarHolder.clear();

//Draw a border progressBarHolder.moveTo(0, 20); progressBarHolder.lineStyle(1, 0x666666); progressBarHolder.lineTo(100, 20); progressBarHolder.lineTo(100, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20);

//Draw the bar progressBarHolder.moveTo(0, 20); progressBarHolder.beginFill(0xCCCCCC, 100); progressBarHolder.lineTo(barWidth, 20); progressBarHolder.lineTo(barWidth, 30); progressBarHolder.lineTo(0, 30); progressBarHolder.lineTo(0, 20); progressBarHolder.endFill();

}

211

Chapter 8

The custom loader created earlier had no designated spot to put initialization code and required a manual test to see if the bytesLoaded() method returned zero. The MovieClipLoader class gives you an onLoadStart event that is a good place for initialization code, and the class deals with some of the intricacies of load startup so that you do not have to.

A good thing to add to this code is an onLoadError event handler. This handler provides a graceful response to an incorrect URL or an interrupted transfer. You have an opportunity to add this event handler in an end-of-chapter exercise.

Examining the Loader and ProgressBar

Components

One of the tradeoffs with using a pre-existing component versus one created from scratch is that there is a balance between complexity and control. Your homemade pre-loader is definitely the most flexible, but also requires the most work. The MovieClipLoader class takes control over how the polling process works during the load, but it makes up for it in reusability. The Loader and ProgressBar components do the most to take over the work of implementing loader code and implementing visual feedback drawing code, but using them restricts you to the features provided by the components.

One drawback to the Loader and ProgressBar components is that they cause Flash to compile the whole component framework into the movie you are creating. The framework together with the two components results in around 32 kilobytes of additional file size that needs to be loaded. This makes these components unsuitable for the initial loading of content, because it takes a while before the progress status makes it to the screen. Instead, these components work better for situations where you need to load chunks of content in a piecemeal fashion after the main content has loaded.

Before going into how to implement the Loader and ProgressBar components, take a look at their properties, methods, and events.

Loader Component Method, Properties, and Events

The Loader component is a container to load content into, and it can hold either an .swf file or a .jpg file. With version 8 of the Flash player, it also supports .gif and .png files, including those with transparency. Whereas the MovieClipLoader class requires a movie clip to be provided, the Loader component comes with its own movie clip.

There’s only one Loader method, load(), which triggers the start of the load process. It takes either no argument or one single argument. If no argument is given, the contentPath property must have been specified beforehand. If one argument is given, it is a string representing the path to the content to be loaded. load() returns nothing. The following prototype shows the basic form of the load() method:

loaderInstance.load([contentPath:String]) : Void

If the autoLoad property is set to true, then setting the contentPath property automatically triggers the load, making the load() method unnecessary.

212

Pre-Loading Movies

Following is a delineation of the component’s properties:

 

Property

Type

Description

 

 

 

 

 

 

 

 

 

 

 

 

autoLoad

Boolean

If true, content loads immediately upon setting the content

 

 

 

Path property. If false, the loader waits for a load() call.

 

bytesLoaded

Number

The total number of bytes loaded. (Read only.)

 

bytesTotal

Number

The total number of bytes for the content. (Read only.)

 

content

MovieClip

A handle to the movie clip holding the content. (Read

 

 

 

only.)

 

contentPath

String

The path to the loaded content.

 

percentLoaded

Number

The percentage of the content already loaded. (Read only.)

 

scaleContent

Boolean

If true, content scales to fit the size of the loader. If false,

 

 

 

content is not scaled and the loader size adjusts to fit.

 

 

 

 

 

The Loader component has two events, described in the following table.

Event

Type

Description

 

 

 

complete

Listener

Fires when the content has finished loading.

progress

Listener

Fires repeatedly during the load process.

ProgressBar Component Method, Properties, and Events

The ProgressBar component works alongside the Loader component to provide visual feedback of the media load progress. This component has only one method: setProgress(). The setProgress() method is for setting the progress values manually, and works only when the mode property is set to manual. It takes two arguments: first, a value for the total amount loaded and, second, a value for the total to load. The following prototype shows the basic form of the setProgress() method:

progressBarInstance.setProgress(completed:Number, total:Number) : Void

You can use the progress bar in manual mode for purposes other than recording bytes loaded. It can, for example, show a progression of number of files loaded where completed represents the number of files loaded and total indicates the total number of files to load.

The ProgressBar component’s properties are described in the following table.

213

Chapter 8

Property

Type

Description

 

 

 

conversion

Number

Conversion factor for converting bytes loaded into another

 

 

unit for display purposes. Using a value of 1024 converts

 

 

bytes loaded into kilobytes loaded.

direction

String

The direction that the progress bar advances. Values available

 

 

are left and right.

indeterminate

Boolean

If true, an animated striped fill is used instead of a solid fill.

 

 

Used when loading content of unknown size. If false, the

 

 

progress bar advances normally.

label

String

The text to use to indicate loading progress. The text can

 

 

include the key strings %1, %2, %3, and %%. The first is a place-

 

 

holder for bytes loaded, the second is for total bytes, the third

 

 

is for percent loaded, and the final is to show a percent

 

 

symbol. A sample label is %1 out of %2 bytes loaded,

 

 

%3%% complete.

labelPlacement

String

Sets the position of the label relative to the progress bar.

 

 

Possible values are left, right, top, bottom, and center.

maximum

Number

Holds the largest progress value for when the mode property

 

 

is set to manual.

minimum

Number

Holds the smallest progress value for when the mode property

 

 

is set to manual.

mode

String

Controls how progress deals with loaded content. Possible

 

 

values are event, polled, and manual. The value event is

 

 

for working with the Loader component, polled is for working

 

 

with movie clips, and manual is for manual setting the progress.

percentComplete

Number

Indicates the percentage of the content that has been loaded.

 

 

(Read only.)

source

Object

A source of progress information. Can be a Loader component

 

 

or a movie clip.

value

Number

Indicates the progress that has been made between the mini-

 

 

mum and maximum properties when the mode property is set

 

 

to manual.

The following table delineates the ProgressBar component’s two events:

Event

Type

Description

 

 

 

complete

Listener

Fires when the content has finished loading.

progress

Listener

Fires repeatedly during the load process.

214

Pre-Loading Movies

Implementing the Loader and ProgressBar Components

Unlike a class, which is either available directly from the player or is compiled into the .swf by design, components are not automatically included in the compile. You can call the code to create a new instance on the stage, but if the component isn’t in the library, it won’t appear on the stage. You have two ways to place a copy of a component in the library:

Drag one of each component needed from the Components panel onto the stage and then delete each one from the stage. Dragging a component to the stage automatically places the component in the library. This is the standard approach in the Flash MX 2004 authoring environment.

In the Flash 8 authoring environment, drag each component needed from the Components panel onto the Library panel.

With that done, you can create instances of the two components:

this.createClassObject(mx.controls.Loader, “loaderComponent”, ; this.getNextHighestDepth());

this.createClassObject(mx.controls.ProgressBar, “progressComponent”, ;

this.getNextHighestDepth()); progressComponent._x = 50; progressComponent._y = 100;

This code creates an instance of the Loader component and of the ProgressBar component and places them on the stage with the instance IDs loaderComponent and progressComponent. It also positions the progress bar so that it will show in the middle of the loader component. The createClassObject() method enables you to place any component on the stage programmatically instead of having to manually place each instance on the stage. This method is described in more detail in Chapter 9.

Next, you place the code to actually work with these components. By setting the source property of the progress bar to point to loaderComponent, the two are linked and the progress bar automatically reflects the status of the loader component:

this.createClassObject(mx.controls.Loader, “loaderComponent”, ; this.getNextHighestDepth());

this.createClassObject(mx.controls.ProgressBar, “progressComponent”, ; this.getNextHighestDepth());

progressComponent._x = 50; progressComponent._y = 100;

progressComponent.source = loaderComponent; loaderComponent.scaleContent = false; loaderComponent.load(“http://www.nathanderksen.com/book/trailer.swf”);

Now you have a working progress bar. The source property links up the loader as a source of progress information for the bar to use. The scaleContent property makes sure that the content does not scale to the size of the Loader component; instead, the component resizes itself to accommodate whatever dimensions the content ends up having.

A couple of issues remain. First, the content starts playing before loading is done, and second, the progress bar stays around after loading is complete. These can be dealt with by adding a couple of event listeners:

215

Chapter 8

this.createClassObject(mx.controls.Loader, “loaderComponent”, ; this.getNextHighestDepth());

this.createClassObject(mx.controls.ProgressBar, “progressComponent”, ; this.getNextHighestDepth());

progressComponent._x = 50; progressComponent._y = 100;

var loadHandler:Object = new Object(); loadHandler.progress = function(eventObject:Object)

{

loaderComponent.content.stop();

}

loadHandler.complete = function(eventObject:Object)

{

loaderComponent.content.play(); progressComponent._visible = false;

}

progressComponent.source = loaderComponent; loaderComponent.scaleContent = false; loaderComponent.addEventListener(“progress”, loadHandler);

loaderComponent.addEventListener(“complete”, loadHandler); loaderComponent.load(“http://www.nathanderksen.com/book/trailer.swf”);

Here, two events are defined and then bound to the Loader instance. Unfortunately the Loader component only provides a progress event and a complete event. As a result, the initialization code to stop the playback of the loaded movie clip until it is complete has to go into the progress event handler. This means that the initialization code is called many times when it only needs to be called once, but that’s not enough to hamper performance.

Note the amount of code that is needed to implement the Loader and ProgressBar components versus the MovieClipLoader class and versus our homegrown loader. The homegrown loader code took around 43 lines of code to implement, the MovieClipLoader class took roughly 38 lines of code, and the component implementation took about 15 lines of code. Most of this savings in code from using the components comes from replacing the drawing function with two lines of code to use the ProgressBar component. This component can also work with the MovieClipLoader class, as you see in the exercises at the end of this chapter.

One frequent question that developers ask is how to customize the appearance of the Loader component. The setStyle() method that is available for any component provides a capability to customize aspects of component appearance. The following snippet shows how the text color, text size, and progress bar color properties can be changed:

progressComponent.setStyle(“color”, 0x0000CC); progressComponent.setStyle(“fontSize”, 14); progressComponent.setStyle(“themeColor”, 0xCC0000);

The styles that can be changed for the Loader component are described in the following table.

216

 

 

 

Pre-Loading Movies

 

 

 

 

 

Style

Type

Description

 

 

 

 

 

themeColor

String or

Color to use for component accents, in this case the color

 

 

Number

for the progress bar itself. Possible values are haloGreen,

 

 

 

haloBlue, haloOrange, or a numerical color value.

 

color

Number

Color for label text.

 

disabledColor

Number

Color for label text when the component is disabled.

 

embedFonts

Boolean

Set to true if the font specified in the fontFamily style is

 

 

 

an embedded font, set to false otherwise.

 

fontFamily

String

The name of the font to use for the label.

 

fontSize

Number

The pixel size of the font to display for the label.

 

fontStyle

String

The style of the label text. Possible values are normal and

 

 

 

italic.

 

fontWeight

Number

The weight of the label text. Possible values are bold and

 

 

 

none.

 

textDecoration

Boolean

Indicates whether the label text should be underlined.

 

 

 

Possible values are underline and none.

 

barColor

Number

The color of the progress bar. Has no effect with the default

 

 

 

Halo theme.

 

trackColor

Number

The color of the progress track. Has no effect with the

 

 

 

default Halo theme.

Strategies for Using Pre-Loaders

The structure of your main project determines in part how you implement a loader. Two approaches to consider are the monolithic movie approach and the split-up movie approach.

The Monolithic Movie Approach

If having a very responsive interface is important, or if you are just looking for a simple project structure and straightforward implementation, the monolithic movie approach is likely the one you will want to use. This approach suffers from a longer initial load time but benefits from quicker response once the movie has loaded. Many ways of implementing a pre-loader for a monolithic movie exist, only one of which we will talk about, which is the loader shim technique. This technique actually makes use of two movies. The first movie is the loader movie, sometimes referred to as a loader shim, which, because of its small size, loads to the user’s browser very quickly. Once loaded, the shim loads the primary .swf. This technique is very easy to implement. Just develop your project as you normally would, and then at the end create the loader shim and give it the path to your main movie.

217