devxlogo

Loading External Assets in Flash with Transitions

Loading External Assets in Flash with Transitions

ow can I add a fade transition when I load, or unload, external SWF movies?

This question arises because, when loading a movie, the loaded content begins to appear as soon as there is enough data to display the beginning frames of the movie. This causes the loaded content to “pop in” without any transition. When unloading content, the effect is similar. An unloaded movie just disappears without any additional ceremony. How then, can a user load an external movie, with a nice fade in? Or, for that matter, fade out the current movie when unloading content?

One way to do this, of course, is to add a timeline fade-in at the beginning, and a timeline fade-out at the end, within every external movie. This requires no scripting and can be accomplished by using a motion tween to change the alpha of the beginning and ending frames in each external file.

However, this not only requires a lot of additional tedious work, it also imposes strict limitations on the loaded movies in that each file must fade in every time it is loaded and fade out every time the end of the movie is reached. Ideally, you want a more modular solution that would allow you to fade in the movie when you wanted to, or “pop” it in immediately if preferred. In this tutorial, I’ll pursue this with a simple scripting approach to fade loaded movies that requires no asset modification.

To answer the question that inspired this article, I’ll be using three external SWF files to create a slide show. They feature the amazing drawing collages of Tony Fitzpatrick, used by kind permission from TonyFitzpatrick.com. The following technique will also work equally well with animated and/or interactive SWFs or, as of Flash MX and later, with simple JPG files.

Author’s Note: To follow along with this article, download the source files here.

The Setup
To create the master file, I’ll use a base movie as the main controller, and then I’ll load all SWFs into two target MovieClips. This will allow me not only to fade a movie in and out when loading and unloading, but also to easily cross-fade between the two SWF files. If I were to load the next SWF into the same MovieClip, it would immediately replace the first. Further, if I want to add a continuous soundtrack, for example, I can do so in the main controller movie, and the loading/unloading process won’t interrupt the audio playback.

The external SWF files I’ll be loading are 380 x 500 pixels, so I’ll size my main movie at 380 x 525 to allow room for the single other asset I’ll need: a button to switch through the slides. I’ll give the button an instance name of “nextButton”.

The Code
To begin, I’ll need content to work with, so I’ll put the pathnames to the three external SWFs into an array for easy access.

swfArray = new Array("red_bird.swf", "chinatown_dragon.swf", "working_beast.swf");

Next, I’ll need two MovieClips into which I’ll load the SWFs. I can create them in the main timeline on the fly using createEmptyMovieClip, naming them “target1” and “target2,” and loading them into levels 1 and 2, respectively.

this.createEmptyMovieClip("target1",1)this.createEmptyMovieClip("target2",2)

Next, I’ll start with the first slide loaded into target 1, and set the alpha of target 2 to zero so it can fade in when the slide is changed. I also want to keep track of which target is active at each press of the button, and which position in the content array was last used. I’ll initialize each of these variables using the first target and the first slide in the array, respectively.

target1.loadMovie(swfArray[0]);target2._alpha = 0; activeTarget = target1;currentIndex = 0

To control the fading, I want to add an enterFrame event handler to the main movie that will fade down a new object called “obj1” until it reaches an alpha of zero, and fade up a new object called “obj2” until it reaches an alpha of 100.

this.onEnterFrame = function() {      if (obj1._alpha > 0) {            obj1._alpha -= 10;      }      if (obj2._alpha < 100) {            obj2._alpha += 10;      }};

There are two handy things to notice about this function. First, by using new objects, we can define them by swapping the target MovieClips at each button press. This eliminates the need to write separate conditionals that determine what to do if clip1 is active and what to do if clip 2 is active. Second, by adding the conditionals, we eliminate alpha values that are either negative or above 100, making the fades much more responsive and accurate.

Finally, we need to add an onRelease event handler to the button. This does three things. First, it populates the object variables discussed above, as well as the relevant tracking variable, activeTarget, by switching between target1 and target2, depending on which was most recently active. Second, it increments the swfArray current index variable, sending it back to zero if the last index has just been used. Third, it loads the next SWF into the MovieClip currently referenced as obj2.

nextButton.onRelease = function() {      if (activeTarget == target1) {            obj1 = target1;            obj2 = activeTarget = target2;      } else {            obj1 = target2;            obj2 = activeTarget = target1;      }      if (currentIndex < swfArray.length-1) {            currentIndex++      } else {            currentIndex = 0      }      obj2.loadMovie(swfArray[currentIndex])}

Putting all of this together, the first slide will load automatically, and each time the button is pressed, the obj1 MovieClip will fade out and the obj2 MovieClip will load the next SWF and fade in.

Memory Management
One downside to cross-fading the loaded content is that everything has to be in memory at once. This doesn't mean much for this sample controller movie, because it only contains a single button. However, your movie will almost certainly be more involved, and in any case, both external SWFs have to be in memory at once. Depending on how large and how processor-intensive your movies are, this can put a strain on RAM and/or performance. But what if you could get rid of the file you don't need any more?

To see this next exercise in action, add the following line at the end of the enterFrame event handler:

trace("target1: " + target1.getBytesTotal() + " target2: " + target2.getBytesTotal())

This will show you the size of the first SWF and the size of the second SWF and, most importantly, it will show you that both remain in memory before you edit the script. However, you can add a movie unload command to one of the target MovieClips to purge the SWF that is no longer needed.

Add the following to the end of the button handler:

      obj1.onEnterFrame = function () {            if (this._alpha <=0 ) {                  this.unloadMovie();                  delete this.onEnterFrame;            }      }

Because you're swapping your target MovieClips, you always know that obj1 contains the last viewed content and is fading out, and obj2 contains the next SWF in line and is fading in. So, you can add a command that says to unload obj1 when the alpha reaches zero or less.

Lastly?and this is important?you need to make sure that the MovieClip referenced by obj1 doesn't continue to unload its own content. This would make it impossible to reload the target. So, once the unload instruction is given, delete the event handler preventing further execution. The EnterFrame handler gets recreated every time the next-slide button is pressed, so it will be ready again for the next swap.

Other Options
That's it, you're done. As I mentioned at the start of this article, there are many ways to accomplish this goal. You could take a similar approach with levels, instead of MovieClips, for example. I prefer to use MovieClips because I feel that it gives me more control, and some people think it can be easier to manage variables if you keep everything within one level. Another option would be to create a component that you could use, instead of a button, for instance (no pun intended), that would handle all of this for you with just a quick configuration of some parameters. Finally, you could create a class file that could handle most of this for you that you could keep in a class library for future use.

I hope some of you take these suggestions and run with them. If you create your own version of this utility, send it along. I would love to see what you've done with it. If you have a question you'd like answered, send it to me and I'll try to work it into a future story.

devxblackblue

About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist