Thursday, December 3, 2009

Preloading in ActionScript 3.0 Part 1

Exercise Files:
Preloader01_Start.fla
allin.swf

In this tutorial, we are going to learn how to create a preloader in Flash using ActionScript 3.

What is a preloader and what is it for?
Flash movies tend to have larger than average file sizes compared to HTML websites. So when you create a Flash website, chances are, it will take a while to load every time a user visits it. That's why it's important to give the user an indication regarding how much longer he or she has to wait. This can be done by adding a preloader to your Flash website. A preloader is simply a kind of visual feedback that shows the user how much of the Flash website has already been loaded. A simple preloader can show nothing more that just a basic progress bar and some text that displays the loading percentage, while other Flash websites will have fancier preloaders that contain more complex animation and design. Regardless of the complexity of the preloader that you choose to make, it's always a good idea to have one for your Flash website. Without a preloader, the visitor might just get a blank browser window at first and think that the website is broken. And instead of waiting for the site to load, the user will more likely end up leaving your website.

How can I create a preloader in Flash?
There are a couple of methods that you can use to create a preloader in Flash. The method that we will take a look at in this tutorial involves the use of 2 Flash movies. One would be your actual Flash movie or website, while the other Flash movie is the one that will preload the Flash website. So here, we have a dedicated Flash movie that will do the actual preloading.


What's going to happen is that the Flash website gets loaded into the preloader Flash movie.


As the Flash website gets loaded into the preloader Flash movie, the preloader Flash movie will calculate and display the loading progress. To do this, the preloader Flash movie needs to contain the ff:
  • the ActionScript code that does the preloading
  • the visual elements of the preloader (such as the progress bar and the percentage text field)


 This tutorial comes with 2 exercise files:
  1. Preloader01_Start.fla
    This will generate our preloader Flash movie. This is where we will put the ActionScript 3 code for preloading a Flash website or file.
  2. allin.swf
    This is the Flash movie that we will be preloading. It just contains a picture of some poker chips and some animated text that says "all in".

Make sure that you save both files in the same folder. Otherwise, the preloader Flash movie might not find the Flash movie that we want to preload.

Let's first take a look at the contents of our preloader Flash movie. So go ahead and open the Preloader01_Start.fla file. On the stage you will see a movie clip instance named progressBar_mc and a dynamic text field named percent_txt.


They will both be used to indicate the loading progress. The progress bar gets fuller as the loading progresses, and the text field shows the percentage value of how much has already been loaded.

If you look at the main timeline, you'll see that it has only one frame. But if you go inside the progress bar movie clip, you'll see that it contains some animation inside it. You can double-click on the progress bar movie clip to go inside its timeline.  

NOTE: If you have trouble selecting the progress bar, make sure that you click on the border.

Once you're inside the progress bar movie clip's timeline, you'll see that it contains a layer named bar that has a shape tween.


This shape tween shows the progress bar going from empty to full. You can test the movie to see how it looks like. But when you test it, you'll just see the progress bar animate and loop endlessly. You won't see the text field update itself, and you won't see anything load yet. That's because we haven't added any code.

This progress bar animation will be used to represent the loading progress. You'll notice that the animation inside the progress bar movie clip's timeline is made up of 100 frames.


This is not an arbitrary number. The animation really has to have 100 frames because we want it to represent 100%. Each frame of the animation, represents one percent of the file that we are going to preload. The great thing about this is that you can just replace the animation with something else if you want a different progress bar. Just make sure that it has 100 frames. It doesn't even have to be a progress bar. You can be more creative with your preloader animation if you want. But don't go too overboard with your preloader animation. If you do, then your preloader Flash movie might end up having such a large file size that it will end up needing its own preloader.

REMEMBER: The animation is INSIDE the progress bar movie clip's timeline, NOT on the main timeline.

So let's begin adding our ActionScript 3 preloader code. If you're still inside the timeline of the progress bar movie clip, make sure that you go back to the main timeline by clicking on the Scene 1 link.

Once you're back on the main timeline, select frame 1 of the Actions layer and then open up the Actions panel.

STEP 1

First, let's stop the progress bar animation. We don't want the progress bar to start moving right away. We only want it to start moving once the loading process has started. So make it stop using the stop() method.
progressBar_mc.stop();

STEP 2

Then create a Loader and a URLRequest object:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

What are these objects for?
Loader objects are used to load external SWF files into a Flash movie. So this Loader object is going to be responsible for loading the Flash movie that we want to preload. Without this object, then we would not be able to load our main Flash movie into our preloader Flash movie. In our example, the external file that we want to load would be allin.swf.

NOTE: Aside from being able to load SWF files, Loader objects also have the ability to load JPG, PNG, and GIF files.

The URLRequest object is used to specify the path to the external file that you would like to load. This is what will tell the Loader what it's supposed to load. In this example, we want to load the allin.swf file, so that's why we typed the file name inside the parentheses of the URLRequest() constructor.

NOTE: You must pass the file name or path to the URLRequest() constructor as a string. So it should be in quotation marks.

So to recap, the Loader object loads the file, while the URLRequest is used to specify the path to the file that needs to be loaded.

STEP 3

At this point, let's now load the external SWF file into our preloader flash movie. But before we continue, I must warn you: after we load the external SWF file, we won't see it yet. But that's ok. We'll fix that later on.

To load the external file, we use the load() method of the Loader class. The load() method needs an argument. It needs to know which file you want to load. We've already specified that when we created the URLRequest object. So we simply pass the URLRequest object as an argument to the load() method.

So let's go ahead and use myLoader (our Loader object) to load allin.swf (the external SWF file that we want to preload as specified in the myURL URLRequest object) using the load() method. Go back to the code and add the load() statement highlighted in bold:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

myLoader.load(myURL);

So this new line that we've added tells the myLoader object to begin loading the file requested by the myURL object (which is allin.swf). Without this line, then the loading will not start.

But remember, as I've mentioned earlier, when we test the movie, we won't see the file come out on the stage just yet. That's because we've told Flash to load it, but we haven't told Flash to display it yet. Loading and displaying are two different things. But don't worry, we'll fix that later on.

STEP 4

Next, we'll need some event handlers. These event handlers that we're about to add are events that relate to the loading progress and loading completion of our external file. These events are:
1. ProgressEvent.PROGRESS
This event refers to the progress of the loading process. It is active all throughout the time that the external file is being loaded. The event is dispatched every time new data from the external file is being loaded into the Flash document by the Loader.
2. Event.COMPLETE
This event is dispatched when the external file has successfully completed the loading process.

I'll explain what these event handlers will do later on, but for now, add the following code highlighted in bold:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

myLoader.load(myURL); 

myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);

function loading(e:ProgressEvent):void
{
//This will contain the formula that will calculate the loading progress
//as well as the code that will control the progress bar animation
//and the text field output
}

function loaded(e:Event):void
{
//Here, we will specify what will happen once the file has loaded successfully
}

NOTE: These two event listeners that I just mentioned are NOT added directly to the Loader object. You add them to the contentLoaderInfo property of the Loader object instead. So instead of typing myLoader.addEventListener(...), you'll type in myLoader.contentLoaderInfo.addEventListener(...).

STEP 5

Right now, we just created 2 empty event listener functions. One for ProgressEvent.PROGRESS, and another one for EVENT.Complete.

Let's go ahead and complete the loading function first. This function is the one that we assigned to the ProgressEvent.PROGRESS event, so this means that this function will get called numerous times - it will be called each time new data from the external file gets loaded into our preloader Flash movie. So basically, this event keeps happening as the loading progress occurs (hence the name ProgressEvent.PROGRESS). Because of that, we can use it to write some code that will calculate and update the user regarding the loading progress.

Go to the loading function, and add the following lines highlighted in bold:
function loading(e:ProgressEvent):void
{
var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
percent_txt.text = nPercent.toString() + "%";
progressBar_mc.gotoAndStop(nPercent);
}

So now we just added 3 new lines inside the loading function. Let's try to understand what these lines are for.

1st line: var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
The first line calculates for the loading percentage. In order to calculate for the loading percentage, you will need to get the amount of bytes that have already been loaded, and divide it by the external file's total number of bytes. And then we multiply that value by 100 to convert the value into percent.

So how do I get the number of bytes that have been loaded and the total number of bytes?
This information automatically gets passed to the ProgressEvent.PROGRESS listener function (which in this case is our loading function). The number of bytes that have already been loaded can be retrieved using the bytesLoaded property, while the file's total number of bytes can be retrieved using the bytesTotal property. To access these properties, we use our event object - e:

e.bytesLoaded - the number of bytes that have been loaded
e.bytesTotal - the external file's total number of bytes (or its total file size)

Then divide those two values and multiply by 100 to get the percentage value.
e.bytesLoaded / e.bytesTotal * 100;

Then use Math.round() in order to round the value to a whole number.
Math.round(e.bytesLoaded / e.bytesTotal * 100);

Then we assign the equation to a variable (which I named nPercent):
var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);

And that is what the first line in the loading function means.

We will then use this nPercent variable for 2 things: (1) to display the percentage value in the text field and (2) to control the animation of the progress bar.

2nd line: percent_txt.text = nPercent.toString() + "%";
The second line in the loading function displays the value of nPercent in the dynamic text field on the stage. I've named the dynamic text field percent_txt. The text property of the TextField class lets you assign the text that you want to appear in the text field. So we assign the nPercent variable to it in order to display its value in the text field. However, nPercent is of the Number data type. Text fields can only display strings so we simply convert nPercent to the String data type using the toString() method. If you want the number to appear with a percent sign, then simply concatenate the value with the percent(%) character.

NOTE: The toString() method will not convert the numbers into letters. For example, 4 will not be converted to four. It will still be displayed as 4 but will be treated as a String instead of a Number. We need to do that so that the text field will accept it.

3rd line: progressBar_mc.gotoAndStop(nPercent);
The last line in the loading function controls the timeline of the progressBar_mc MovieClip. Recall that there is a 100 frame animation inside this MovieClip. On frame 1, the progress bar is empty. As the animation progresses, then the progress bar fills up until it is completely filled at frame 100. There's a reason why we want the animation to have 100 frames. We want to associate each frame number with the percentage of data that has been loaded. If 20% of the external file has been loaded, then we want the playhead to move to frame 20 of the progress bar animation. If 50% of the data has been loaded, then we want the playhead to move to frame 50, and so on... In order to do that, we can use the gotoAndStop() method of the MovieClip class and pass nPercent to it. So as nPercent increases, then the animation moves forward in sync with the percentage value.

NOTE: It is important that nPercent is rounded to a whole number because of this line. That's why we used Math.round() to round it. We cannot tell Flash to go to a frame no. 25.43, for example, since there is no frame no. 25.43. Frame numbers are always whole numbers.

And that completes our loading function. In the next step, we'll test the movie, but we'll simulate the download process when we do the testing. This means we'll make the movie behave as if we're actually viewing it online, so instead of finishing the loading process right away, we'll wait a while as if we were actually viewing it online. We want to simulate the download so that we can actually see the progress bar update. If we didn't simulate the download, then everything will just load right away.

STEP 6

How do we simulate the download?
First, you must test the movie. The keyboard shortcut for testing the movie is ctrl + enter (Windows) or cmd + return (Mac).

Once you test the movie, you should see the progress indicators go to 100% right away. This means that the external SWF file has already been loaded (but remember, you won't see it yet!). That was pretty fast! We just tested the movie, and all of sudden it loads right away. That's because our files are just in our hard drive. So let's change a few settings that will make Flash pretend as if we were testing this online instead.

So while the test movie window is still there, go to the View menu. If you're on a Mac, the View menu can be found in the menu bar at the top of your Flash workspace. If you're on Windows, the View menu can be found at the top of the actual test movie window.

So go to View, and then go to Download Settings, and then choose the desired download speed. Let's choose the 56K speed. This means that when we test the movie, Flash is going to behave as if we were viewing it online using a 56K connection. This is a pretty slow connection, so our small external SWF file should take about 7 to 8 seconds to load.

Now that we've chosen a speed, go to View again, and then choose Simulate Download. This will test the movie again, but will behave as if we we're viewing it with a 56K connection. This time, you should now see the progress bar update.

At this point, you still won't see the external SWF file appear on the stage. But it is being loaded. We'll be fixing the code soon so that we actually get to see the allin.swf file once the loading completes.

STEP 7

Let's now go to the loaded function and put some code inside it. The loaded function is the listener function that we assigned to  EVENT.Complete. This means that this function will get called, once myLoader finishes loading the external SWF file. So whatever it is that we want to happen once the loading is complete, we should place in this function.

One of the first things we want to do is to remove the progress bar and text field from the stage. Some people might want to leave these visible, but I prefer to remove them so the stage won't be so cluttered.

So go to the loaded function, and add the following lines:
function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
}

Once the loading is complete, these 2 lines will remove the progressBar_mc and percent_txt display objects from the stage.

NOTE: Another option would be to use the visible property:
progressBar_mc.visible = false;
percent_txt.visible = false;

STEP 8

So now, test the movie again. Be sure to simulate the download. You should see the progress bar and text field disapper once it gets to 100%.

STEP 9

So now, let's go ahead and make sure that we actually see the externally loaded SWF file once the loading is complete. To do that, we need to add it to the display list. If we can remove things from the display list using removeChild(), then we can add things to the display list using addChild(). When you add something to the display list, it means that the display object can now be seen.

So go back to the loaded function and add the following line highlighted in bold:
function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
addChild(myLoader);
}

So here, we are adding myLoader to the display list. We should now see the externally loaded SWF file show up on the stage once the loading is complete.

But why are we adding myLoader? Shouldn't we add allin.swf?
allin.swf is actually inside myLoader. When a Loader object loads an external file, the external file is actually loaded inside the Loader object itself. So the external file becomes a child of the Loader object that loaded it. So if you add the Loader to the display list, then its child gets added as well.

STEP 10

So now, go ahead and test the movie. Be sure to simulate the download as well. And you should now see the externally loaded SWF file appear on stage once the loading is complete.

STEP 11

Lastly, I want to remove a few more things once the loading is complete. I want to remove the event listeners that we created. So go back inside the loaded function and add removeEventListener() statements for the ProgressEvent.PROGRESS and Event.COMPLETE listeners.

function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
addChild(myLoader);
myLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaded);
}

Why are we removing them?
In this case, it's because we no longer need them once the loading is complete. It's a good habit to remove listeners that you no longer need. It might help you save more computing resources in the long run, especially if you have a pretty heavy Flash movie. But if your Flash movie needs to preload something again, you might need to keep the event listeners available instead of removing them. Or you can also just add them again at some point in your code. Likewise, you should add the progressBar_mc and percent_txt display objects back to the stage if your Flash movie needs to preload another external SWF file. If you try to remove something that's already been removed using removeChild(), then you'll get an error message. So be sure to add those back if you need them again. But in this example, we're only loading one external SWF file, so there won't be a need for that.

NOTE: Each Loader object can only load an external file one at a time. If you want to load multiple external files all at once, then you should create multiple Loader objects.

And that completes our preloader. Here's the full code:
progressBar_mc.stop();

var myLoader:Loader = new Loader();
var myURL:URLRequest = new URLRequest("allin.swf");

myLoader.load(myURL); 

myLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded);

function loading(e:ProgressEvent):void
{
var nPercent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
percent_txt.text = nPercent.toString() + "%";
progressBar_mc.gotoAndStop(nPercent);
}

function loaded(e:Event):void
{
removeChild(progressBar_mc);
removeChild(percent_txt);
addChild(myLoader);
myLoader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, loading);
myLoader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loaded);
}

Go to Part 2 (Preloading in ActionScript 3.0)

Sunday, November 1, 2009

Flash CS4 Drawing Tools

The following tools highlighted in the picture below can be used to draw things on the stage of your Flash CS4 document:

The tools highlighted in the image are (clockwise):
Pen tool, Line tool, Rectangle tool, Deco tool, Brush tool and Pencil tool

Some of the tool icons that you see have a tiny little triangle on the lower-right corner. Click and hold these icons and you will see a menu pop out. This menu contains other tools that you can use in place of the one that's currently visible on the toolbar. Simply click on the new tool that you want to use in order to switch to that tool.

Monday, May 4, 2009

Photoshop: Copying a Layer onto a New Document



You can use the Move tool to copy a layer onto a new document.

Choose the Move tool from the Tools panel. Select the layer you want to copy then click and drag it to the new document where you want to copy it to.

To copy multiple layers, make multiple layer selections in the layers palette.
  • To make multiple layer selections in the Layers palette, hold down either the shift key or the control key and click on the layers that you would like to select (if you're on a Mac, you can use either the shift key or the command key).
Then from the layers palette, drag the layers onto the new document.

Sunday, April 19, 2009

Intro To Adjustment Layers In Photoshop

This video from TutCast.com (IceFlowStudios on YouTube), talks about using adjustment layers and its benefits.

Photoshop Retouching Tools: Clone Stamp, Healing Brush, Spot Healing Brush, Patch Tool

This video by IceFlowStudios on YouTube talks about 4 different Photoshop tools that can be used to retouch images: the Clone Stamp, the Spot Healing Brush, the Healing Brush and the Patch tool.

I would just like to add a few things regarding some of the tools:

Healing Brush
When you follow along the tutorial, check the Healing Brush tool options to verify that for the Source options, Sampled is selected. The other option would be Pattern. Selecting the Pattern option lets you retouch areas based on a pattern which you can select from Pattern pop-up palette.

Patch Tool
In the Patch tool options, you can choose to patch the source or to patch the destination. In the example demonstrated in the video, the source was being patched - the area that was originally selected was retouched. If you choose to patch the destination, then it would work the other way around. The area that you originally select will be the area to be sampled from, and the new area that you drag the selection to will be retouched.

Using The Clone Stamp Tool

Here's a 4-minute tutorial from IceFlowStudios on YouTube that demonstrates how to use the Clone Stamp tool in Photoshop. NOTE: When you follow along this tutorial, make sure that you select the Clone Stamp tool and NOT the Pattern Stamp tool. The speaker in the video mentions the keyboard shortcut for accessing the Clone Stamp tool (which would be the S key), but if the Pattern Stamp tool is active in the Toolbar, then you'll end up selecting that. So do verify that you actually have the Clone Stamp tool selected as you follow along this tutorial.

How To Reset Back To The Default Photoshop Settings

There are times when you may accidentally change some of the Photoshop settings and then can't quite figure out how to change them back. Or perhaps you work on a shared computer and the users before you tweak the settings often. When this happens, you may want to reset back to the default settings. Here's how:
  1. Launch the Photoshop application and immediately hold down the CTRL+ALT+SHIFT (Windows) or COMMAND+OPTION+SHIFT (Mac) keys.
  2. Click Yes when you are prompted with the message that asks "Delete the Adobe Photoshop Settings File".

When your Photoshop application initializes, it should now have reverted back to the default settings.

Thursday, April 16, 2009

Introduction to Layer Masks in Photoshop

Layer masking is a very useful feature in Photoshop that allows you to hide some areas (make them invisible) of a layer. A layer mask can be altered using the brush tool. To hide areas using a layer mask, you must paint the mask using black. To make areas fully visible, you use white. Using gray will make areas translucent (not quite visible, but not quite invisible as well).

I've posted three different videos about layer masks here. They're all introductory videos about layer masks, but there are some things in one video that you might not learn from the others, so I've decided to add them all here.

This first one is by Nathan Ridley from Graphics District. He uses Photoshop 7 in this tutorial, but you can still follow along even if you're using CS2 or CS3.

Introduction To Layer Masks In Photoshop 7 from Nathan Ridley on Vimeo.

This next one is from IceFlowStudios on YouTube. The speaker also talks a little bit about vector shapes in the end. But it's ok if you're not familiar with what vector shapes are and what you can do with them. The main point of these videos is for you to learn how to use layer masks and you don't really need knowledge in vector shapes in order to achieve that. The speaker simply wanted to show an example that uses a layer mask on a vector shape. The Photoshop version used in this video is CS3.


This last one is from TutorialStop.com. The Photoshop version used in this video is CS3.

If you want to use the images in this video, here are the links:
Waterfall
Highway
Be sure to read the Creative Commons license applied to both images.

Wednesday, April 15, 2009

Photoshop's Selection Tools

Nathan Ridley of Graphics District talks about the different Selection tools in Photoshop and how some keyboard keys can be used to aid the Photoshop user in making selections.

Photoshop version used in this video: CS2

Part 1

Introduction To The Selection Tools In Photoshop CS2: Part 1 from Nathan Ridley on Vimeo.

Part 2

Introduction To The Selection Tools In Photoshop CS2: Part 2 from Nathan Ridley on Vimeo.

Photoshop's Move Tool

In this tutorial, Nathan Ridley of Graphics District talks about the Move tool.

Photoshop version used in this video: CS3


The Move Tool - A Photoshop CS3 Tutorial from Nathan Ridley on Vimeo.

Introduction To Photoshop Layers

This video by Nathan Ridley of Graphics District shows you the basics of working with layers in Photoshop.

Photoshop version used in this video: CS3


Introduction To Layers In Photoshop CS3 from Nathan Ridley on Vimeo.

How to Pass Additional Parameters to AS3 Event Handler Functions

I've recently made the leap to AS3, and one of the very first questions I wondered about was how I could pass extra arguments to event listener functions. From what I understand, event listener functions in AS3 can only have one parameter, which is for the event object that gets passed when the event is triggered. I did some searching and found an article by Rich Schupe that explains a few different methods on how one can pass arguments with events in AS3. He focuses mainly on teaching the reader how to create a custom event class in order to address the issue at hand. But as I've mentioned earlier, he does provide other methods as well (that do not require the creation of a custom class). And if you continue reading through the article's comments, Jonathan Ross offers up another simple alternative that involves nesting the event listener function within a function and passing the arguments through the containing function:
function someFunction(arg1, arg2, arg3...):returnType
{
     // Use the arguments anyhwere within the function body
     eventSource.addEventListener(EventType.EVENT_NAME, listenerFunction);

     function listenerFunction(e:EventType):void
     {
          // do something
     }
}

someFunction(arg1, arg2, arg3...);

Example:
function initButtons(_btn:SimpleButton, greeting:String):void
{
     _btn.addEventListener(MouseEvent.CLICK, greetPerson);

     function greetPerson(e:MouseEvent):void
     {
          trace(greeting);
     }
}

initButtons(_btn1, "Hi, John!");
initButtons(_btn2, "Hi, Mary!");
initButtons(_btn3, "Hi, Linda!");

Which method to use really depends on your knowledge in AS3 and the requirements of your project.