DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 7.9 Fading a Movie Clip

7.9.1 Problem

You want to programmatically fade a movie clip.

7.9.2 Solution

Create a fade( ) method that uses the onEnterFrame( ) event handler method and the movie clip's _alpha property.

7.9.3 Discussion

You can set the value of a movie clip's _alpha property to adjust its transparency. Thus, if you want to set a movie clip's transparency to a single value, you can do so with a single statement such as:

// Set the movie clip's transparency to 50%.
myMovieClip._alpha = 50;

You can repeat this process to achieve a fading effect on the same movie clip. You should do this by placing the property assignment statement within the onEnterFrame( ) method of the movie clip:

// Repeatedly decrement the _alpha of the movie clip.
myMovieClip.onEnterFrame = function (  ) {
  this._alpha--;
};

The valid range for the _alpha property of a movie clip is from 0 (completely transparent) to 100 (fully opaque). However, because ActionScript allows you to set the value outside that range, use an if statement to safeguard against inappropriate values:

// Continuously decrement _alpha, provided it is greater than 0.
myMovieClip.onEnterFrame = function (  ) {
  this._alpha--;
  if (this._alpha <= 0) {
    delete this.onEnterFrame;
  }
};

The preceding code works, but it is not completely efficient and has the potential for some minor errors. The reason is that the working range for _alpha is from 0 to 100, but internally Flash converts all the numbers to a range of 0 to 255. As a result, you can end up with incorrect values using the preceding technique. You can test this for yourself by adding a trace( ) statement to the code:

myMovieClip.onEnterFrame = function (  ) {
  this._alpha--;
  trace(this._alpha);
  if (this._alpha <= 0) {
    delete this.onEnterFrame;
  }
};

Testing the example reveals that the _alpha value is not decremented by 1 each time, as you might expect, and the final result can be negative. To solve this problem, you can use another variable as an intermediary:

myMovieClip.onEnterFrame = function (  ) {

  // Use alphaCount as an intermediate variable. If the value is undefined,
  // initialize it to 99; otherwise, decrement it by 1.
  this.alphaCount = (this.alphaCount == undefined) ? 99 : --this.alphaCount;

  // Assign the value of alphaCount to _alpha. The alphaCount value is always an
  // integer, which is what we want.
  this._alpha = this.alphaCount;
  if (this._alpha <= 0) {
    delete this.onEnterFrame;
  }
};

And, of course, you can do the reverse to fade up a movie clip:

myMovieClip.onEnterFrame = function (  ) {

  // Use alphaCount as an intermediate variable. If the value is undefined,
  // initialize it to 0; otherwise, increment it by 1.
  this.alphaCount = (this.alphaCount == undefined) ? 0 : ++this.alphaCount;

  // Assign the value of alphaCount to _alpha. The alphaCount value is always an
  // integer, which is what we want.
  this._alpha = this.alphaCount;

  // Make sure the value does not exceed 100.
  if (this._alpha >= 100) {
    delete this.onEnterFrame;
  }
};

If you work with programmatically generated fades often, you should create a fade( ) method for all MovieClip objects and add it to a MovieClip.as file for easy inclusion in future projects. The method should accept two parameters:

rate

The rate at which to increment or decrement the movie clip's _alpha property. In most cases, it should be from 1 to 20. If the value 0 is used, then no changes occur to the _alpha property.

up

A Boolean that indicates whether to fade up ( if true) or fade down ( if false).

Here is our custom fade( ) method:

MovieClip.prototype.fade = function (rate, up) {

  // Create a new, nested movie clip to monitor the fade progress. This avoids
  // interfering with any existing onEnterFrame(  ) method applied to the movie clip.
  this.createEmptyMovieClip("fadeMonitor_mc", this.getNewDepth(  ));

  // Define a new onEnterFrame(  ) method for the monitor movie clip.
  this.fadeMonitor_mc.onEnterFrame = function (  ) {

    // Set a Boolean property, isFading, so that other methods know if the movie clip
    // is being faded.
    this._parent.isFading = true;

    // Check whether the movie clip is being faded up or down.
    if (up) {
      // Use an intermediate property to determine the new alpha value.
      this.alphaCount = (this.alphaCount == undefined) ? 0 : 
                         this.alphaCount + rate;

      // If the current _alpha of the clip is under 100, assign the new value; 
      // otherwise, set the value to 100 and delete the onEnterFrame(  ) method.
      if (this._parent._alpha < 100) {
        this._parent._alpha = this.alphaCount;
      } else {
        this._parent._alpha = 100;
        delete this.onEnterFrame;

        // Set isFading to false since the fade is completed.
        this._parent.isFading = false;
      }
    } else {
      // Use alphaCount as an intermediate property to determine the alpha value.
      this.alphaCount = (this.alphaCount == undefined) ? 100 : 
                         this.alphaCount - rate;

      // If the current _alpha is greater than 0, assign the new value; otherwise,
      // set the value to 0 and delete the onEnterFrame(  ) method.
      if (this._parent._alpha > 0) {
        this._parent._alpha = this.alphaCount;
      } else {
        this._parent._alpha = 0;
        delete this.onEnterFrame;
        
        // Set isFading to false since the fade is completed.
        this._parent.isFading = false;
      }
    }
  }
};

Here is an example that uses the custom fade( ) method to fade a movie clip from total opacity to total transparency. This example does not demonstrate the ability of the fade( ) method to incorporate an existing onEnterFrame( ) method.

// Include DrawingMethods.as from Chapter 4 for its drawCircle(  ) method.
#include "DrawingMethods.as"
// Include MovieClip.as from this chapter for its custom fade(  ) method.
#include "MovieClip.as"

// Draw a circle.
_root.createEmptyMovieClip("myMovieClip", 1);
myMovieClip.lineStyle(1, 0x000000, 100);
myMovieClip.drawCircle(100);

// Call fade(  ) with a rate of 5. This fades the movie clip down in 20 frames.
myMovieClip.fade(5);

When you use the fade( ) method on a movie clip where you are also defining an onEnterFrame( ) method, you must define the onEnterFrame( ) method before you call fade( ). Here is an example of how to use the fade( ) method in such a scenario:

_root.createEmptyMovieClip("myMovieClip", 1);
myMovieClip.lineStyle(1, 0x000000, 100);
myMovieClip.drawCircle(100);

// Set the _alpha property to 0 initially so that it can fade up from nothing.
myMovieClip._alpha = 0;

// Create an onEnterFrame(  ) method that moves the movie clip.
myMovieClip.onEnterFrame = function (  ) {
  this._x++;
  this._y++;
};

// Call fade(  ) to fade up. Notice that
 the fade and the movement defined in the
// onEnterFrame(  ) method work simultaneously. If the onEnterFrame(  ) method is 
// defined after the call to fade(  ), the fade(  ) method does not work.
myMovieClip.fade(5, true);
    [ Team LiB ] Previous Section Next Section