[ Team LiB ] |
Recipe 7.9 Fading a Movie Clip7.9.1 ProblemYou want to programmatically fade a movie clip. 7.9.2 SolutionCreate a fade( ) method that uses the onEnterFrame( ) event handler method and the movie clip's _alpha property. 7.9.3 DiscussionYou 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:
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 ] |