Flash
MX Slideshow with Listeners: Using Macromedia
Flash MX to sequentially load jpgs and
display them with fade-in transitions,
using a broadcasting Slideshow component
This sample includes a
simple slideshow component in the library
that can be dragged into and used with
any Flash movie to sequentially load a
specified array of jpgs and display them
with fade-in transitions between slides.
I wanted something in which I could specify
which jpgs to use, how long to hold each
slide in place, how long a transition should
last, what depth the slideshow would be
loaded into, and whether the show should
loop or stop at the last slide. Thus each
of the following properties must be supplied
to the slideshow component:
slides_arr, Array holding urls of
jpg/swfs to be loaded
slideDepth, Integer specifying depth
to start loading slides to
(incremented on each slide display)
fps, Integer specifying movie framerate
so setInterval can emulate
nFrames, Integer specifying frames
to hold slide visible
alphaIncr, Number specifying alpha
change per frame
repeat, Boolean specifying whether
slideshow should loop
I could alternately have specified the
amount of time to wait instead of the
number of frames, and the overall time
for fade-ins instead of amount of alpha
to apply in each frame, and then either
used setInterval or calculated the right
number of frames for an onEnterFrame
loop. In this sample, I use a setInterval
for loading, which executes every 1000/fps
milliseconds (once per frame, though
it doesn't really need to be that), and
an onEnterFrame for the transitions because
that required fewest calculations.
I also wanted my slideshow component to tell me
when each slide has been loaded (in
case my main movie wants to indicate
that),
when all slides have been loaded
(so I can start the slideshow immediately,
or alternately, wait for some intro
animation to finish and then start
the slideshow), and
when all slides have been shown,
so the main movie can do whatever it
needs to then
so the slideshow had to be enabled as
a broadcaster and broadcast messages
for each of these events. I did this
using these built-in broadcasting methods:
ASBroadcaster.initialize(b_obj),
which sets up b_obj as a broadcaster
b_obj.addListener(l_obj),
which sets up l_obj to listen for broadcasts
from b_obj
b_obj.broadcastMessage("routineName",
parameters), which broadcasts
a message that all listeners will
'hear' and can act on if they have
a l_obj.routineName(parameters) function
set up.
The code on the slideshow component follows.
Slideshow is just a movieclip in the library.
It contains code (in frame 1) that defines
the Slideshow class. That code is placed
between #initclip and #endinitclip statements
so that it will be available as soon as
the slideshow movieclip is attached.
Define the Slideshow class
This is the constructor function for the Slideshow class. I also set
up Slideshow as a broadcaster using the built-in ASBroadcaster in Flash
MX, and start the jpgs loading with a call to loadInSeq. These things
should properly be done in a separate init routine, but because I want
them always to be done when a slideshow is set up and for code simplification
I include them in the constructor.
Make the
slideshow class inherit from MovieClip
class
This is done in all components which are to function as movieclips, so
that all properties and methods of the MovieClip class are available
to the new class.
Slideshow.prototype
= new MovieClip ();
Define
the method that will allow jpgs to load
sequentially
The loadInSeq method takes one parameter, i, which specifies the index
of slides_arr which holds the slide to be loaded next. When that slide
has been completely loaded (its _width > 0), the method is called
again with i+1. The other thing that happens when a slide has been completely
loaded is a message is broadcast to indicate that, so that any other
object that is subscribed as a listener to the Slideshow object can act
accordingly. When all slides have been loaded, another message is broadcast.
Slideshow.prototype.loadInSeq
= function(i) {
var slide = this.createEmptyMovieClip("slide" + i, this.slideDepth++);
// hide all slides loading on top of first one
if (i > 0) slide._alpha = 0;
slide.loadMovie(this.slides_arr[i]);
checkLoadedID = setInterval(function(i, mc) {
if (mc["slide" + i]._width > 0) {
mc.broadcastMessage("onSlideLoaded",
i);
clearInterval(checkLoadedID);
// start next one loading (if
not last)
if (i < mc.slides_arr.length-1)
{
mc.loadInSeq(i +
1);
} else {
mc.broadcastMessage("onAllSlidesLoaded");
}
}
},
1000/this.fps, i, this);
};
Define
the method that will start the show
This method assumes that the first slide is currently displayed and keeps
it in place for nFrames number of frames before beginning the transition
to the next slide.
Define
the method that does the fade-in transitions
and hold-in-place in between
In this method, i is first incremented (++i) to get the next slide to
be shown. That slide is placed above the current one with the swapDepths
method and its alpha is set to 0. Then on each frame execution, the top
slide's alpha is incremented by the amount specified in the alphaIncr
property. When this is > 95, a new onEnterFrame loop begins which
keeps the current slide displayed for nFrames frames, and then begins
a new transition with the next slide.
Notice that if you wanted something to happen during slide transitions
(such as an indicator of which slide was being shown), you could add
a broadcast message to this code.
The main movie just sets
up the array of pictures and colors, attaches
the slideshow component, specifying each
of its parameters, and then uses routines
to handle whichever broadcast messages
it wishes to respond to. Here is the code:
Attach
the slideshow, name it, and pass the
parameters it needs
In this code, I attach the slideshow
movieclip to blank_mc (on a layer under
the border that I want to show around
the slides) and give it instance name
uuShow. I specify that I want it placed
at (0, 0), invisible during loading,
movie frame rate of 12 fps, number of
frames to hold each slide in place 24,
alpha change each frame 10, start at
depth 50 (no good reason for that; just
a leftover from my original version,
in which I attached the slideshow to
_root instead of to a blank mc), and
loop the slideshow.
Set
up listener and functions to handle
listened-for events
// tell blank_mc
to listen for events broadcast by
uuShow
blank_mc.uuShow.addListener(blank_mc);
Since blank_mc is a listener to uuShow,
it can have routines to handle whichever
of uuShow's broadcast events we want
it to handle. In this movie, I wanted
to give some kind of indication when
a slide has been loaded, so I created
5 black dots in the movie that turn a
color associated with the slide when
it is loaded. (If you hit Refresh and
watch the dots at the lower right of
the movie, you'll see how fast the slides
are loading in -- quite fast probably
since they're already in your cache now
and not very big pix to begin with).
This code sets up blank_mc's onSlideLoaded
routine to do that:
blank_mc.onSlideLoaded
= function(i) {
(new Color(this._parent["dot"+i+"_mc"])).setRGB(color_arr[i]);
};
Once all slides have loaded, I want
to make the show visible and start it
going with a call to beginTransitions.
There is also a commented out routine
for onShowOver, which will be activated
if repeat is set to false in the parameters
passed to uuShow. There are other commented
out lines in the movie that, if uncommented,
trace the loading and display progress
of each slide in the output window. To
use the component in another movie, just
drag it from the library of this movie
to your other movie, delete it from the
stage, and set up your own code to attach
the slideshow (with attachMovie, as above)
and handle each of the events (setting
up your own blank_mc.onSlideLoaded, blank_mc.onAllSlidesLoaded,
and/or blank_mc.onShowOver routines as
needed, and substituting blank_mc with
whatever you want to attach the slideshow
to).
Wildform
provides a 100% satisfaction guarantee on all our Flash software.
If you are not completely satisfied with our Flash multimedia software
for any reason you may request a refund within 15 days
of purchase.