Lab 3: Image Browser
Click on the screenshot to view the Image Browser in a separate window. Flash security rules prevent the project from running as an element of this page.
Due April 14.
I. Overview
In the third lab, we'll depart from the realm of games and simulations to build something like a real-world application: a utility for browsing a collection of images. This project builds on our encounter with the Loader object in the Montage Engine, and continues our work on multi-part software ensembles involving several object classes.
Click on the screenshot graphic at right to view the live version of the project. Click on any of the small thumbnail images to replace the main graphic at right. Click on the right-pointing arrow to advance to a new set of thumbnails, or the left arrow to view a previous set.
II. Assignment
Departing somewhat from our practice in previous labs, we'll build only part of the complete project during our class session. A crucial component -- the pair of buttons that advanced the thumbnail set four images at a time -- will be left out. Your task, during the three weeks of development time, is to supply the missing code.
Since you'll be doing this without assistance, the payoff for completing this basic task is higher than in the first two labs -- worth at least an A-minus.
The rest of this posting describes the given parts of the Image Browser project: the set of four thumbnails, the main image, and the document class that arranges them, plus the ActionScript file, imageClass.as, that controls image display. It will also explain what pieces are missing, and give you a start on the task of inventing them.
III. Setup and architecture
The starter file, imageBrowser_STARTER.fla, has a few essential elements. There's a single keyframe in a single layer, holding nothing more important than the graphical outlines for the images. There is also a Movie Clip defined in the Library, called button_mc, linked to an ActionScript class called buttonClass: a starter version of this class file is included, but it has no function; this is the part you'll write on your own. Finally, the .fla file is linked to a document class file called imageBrowserDocClass.as. This too is provided, in bare outline, along with another class file called imageClass.as, to which we are coming.
IV. Document class
Like our Montage Engine, the Image Browser uses its document class to instantiate objects and position them on the screen. All our visual layout happens in code.
To explain how this works, let's start by reviewing the visual elements of the project. There are four thumbnail images which appear along the left edge of the window. They have dimensions of 125 x 125 pixels, or one-fourth the size of the larger graphic, which appears at right, measuring 500 x 500 pixels. The final version also includes two buttons, but as we've said, those are for you to figure out.
So let's start with some object variables, one for each of the five graphic elements described above. You might suspect that they'll all be instances of Loader -- and indeed, they all will involve Loader at some point; but we'll be using our own custom class, called imageClass, to deal with this. So we declare and create five instances of that class:
public var mainImage:MovieClip = new imageClass(); public var tn_0:MovieClip = new imageClass(); public var tn_1:MovieClip = new imageClass(); public var tn_2:MovieClip = new imageClass(); public var tn_3:MovieClip = new imageClass();
We use "tn" as shorthand for "thumbnail."
Note the names of these five variables. They are the instance names of our graphic objects. So, for instance, once we've created tn_1 in our document class, other objects in the system will be able to communicate with tn_1 by saying:
MovieClip(root).tn_1.something;
...assuming "something" is the name of a property or method of tn_1.
Next, we'll add two very important variables that will help us manage the operation of our Image Browser:
public var mainCount:Number = 0; public var totalImages:Number = 20;
Remember, this system is designed to move through a series of images four at a time. The variable mainCount tells us which group of four we are displaying at the moment. As usual, we start our count with zero. (You'll see why when we get to the thumbnails.)
It's also necessary to say how many images there are in the set, so that we can say what to do when we've displayed the highest-numbered image. We hard-code this number as 20, since that's the number in our image set.
Now we come to the Constructor method, where we'll make each of our thumbnail graphics visible, arrange it on the screen, and set some crucial properties. To save space, we'll only discuss the first of four code blocks dealing with the thumbnails:
addChild(tn_0);
tn_0.x = 10
tn_0.y = 10;
tn_0.scaleX = 0.25;
tn_0.scaleY = 0.25;
tn_0.offsetCount = 0
tn_0.getImage();
The first thing we do is perform the addChild() method of MovieClip to add tn_0, our first thumbnail, to the Display List.
Next, we tell the thumbnail where to sit on the screen: 10 pixels right and 10 pixels down from the upper left corner. We also set the scale for this object to 25% in both width and height. (This is because we're using the same 500x500 pixel image for both the main display and the thumbnails; not the best strategy in the real world, but a useful simplification for our purposes.)
Next, we set a value for offsetCount, a local variable defined by imageClass (to which we are coming). We'll explain what this variable does when we come to that class definition.
Finally, we call a method called getImage(), also defined in imageClass. As you'll recall from the Montage Engine, this is the chunk of code that tells a Loader object to do its stuff.
As we've said, there are three more versions of the code block we've just detailed, one for each of the other thumbnails. Each block contains appropriate variations. The object names are different, obviously. So are the x and y coordinates, so that the objects sit in distinct locations. The value of offsetCount changes to 1, 2, or 3, respectively. The scale factors and the call to getImage() do not change.
The last bit of our Constructor is a code block, very similar to those above, that sets up the main image display. It looks like this:
//SET UP MAIN IMAGE
addChild(mainImage);
mainImage.x = 155
mainImage.y = 0;
mainImage.offsetCount = 0;
mainImage.getImage();
Now, you'll remember that mainImage is an instance of imageClass, just like all those thumbnails. In other words, it starts out life as just another copy of our image-hosting class. Aside from its instance name, it picks up a few more differences at this point.
Note we skip the scale changes for this one. Since the main image display shows the image at full size, we don't need that bit. We still need offsetCount, set to zero, and the call to getImage(). The function of these details will become clear presently.
Though you'll need to add some lines to the Constructor in order to handle the buttons, that's all we'll discuss for now. Let's get on to the image-hosting class.
V. imageClass
Like all of its kind, this one starts with importations:
import flash.display.MovieClip; import flash.display.Loader; import flash.net.URLRequest; import flash.events.MouseEvent;
Aside from the basic MovieClip, we need Loader and URLRequest to handle JPEGs, and flash.events.MouseEvent to make the object respond to mouse clicks, as described initially.
Within the class definition, we declare and instantiate a few things:
public var myLoader:Loader = new Loader(); public var imgName:String; public var imgRequest:URLRequest; public var imgNum:Number; public var offsetCount:Number = 0;
The first three lines here should be familiar from the Montage Engine project: they're needed to set up and manage our Loader object, called myLoader.
The variables ImgNum and offSetCount are used where we plugged in our random value in the Montage Engine -- but here we'll be specifying a particular image number, according to a definite scheme. More about this in a bit.
The Constructor for this class is fairly brief:
public function imageClass():void
{
buttonMode = true;
addEventListener(MouseEvent.CLICK, onClick);
addChild(myLoader);
}
The property buttonMode makes the cursor change shape when it crosses over any Movie Clip for which this property is true, while that Movie Clip is listening for mouse events. Note that buttonMode does not create an event listener -- that's done in the next line, with addEventListener. (You can omit the setting for buttonMode, and your Movie Clip will still respond to mouse events.)
There's a listener set up for MouseEvent.CLICK, which is exactly what the name suggests, handing off to a callback named onClick. Finally, we use addChild() to place our Loader in the Display List.
Let's look at the callback method next:
public function onClick(event:MouseEvent):void
{
imgNum = MovieClip(root).mainCount + offsetCount;
imgName = "pix/img_"+imgNum+".jpg";
imgRequest = new URLRequest(imgName);
MovieClip(root).mainImage.myLoader.load(imgRequest);
}
There is some similarity here to the callback method we used in the Montage Engine, though that one worked on ENTER_FRAME, while this one is cued to mouse clicks.
The first line does something we didn't do in the earlier project. It adds two value, the first being the value of mainCount stored in the main movie. Until you add the up and down buttons, this value will remain at zero. Again, mainCount indicates which of the five sets of four thumbnails we're currently viewing. It's designed to have five possible values: 0,1,2,3,4. When the value is 0, we're looking at images 0 through 3 (the first four images in the series). When it's at 1, we're seeing images 4 through 7, and so forth.
How does that work? The answer lies in addition.
The other half of our sum is supplied by a local variable called offsetCount. You'll rememember, we place a value in this variable by reaching out to it within the document class (which is to say, the main movie), when we set up the thumbnails. Alternatively, we could have set this value in the Constructor for imageClass. Either way would work.
This variable tells us which thumbnail we're dealing with -- number 0, 1, 2, or 3, in the current set of four. (Remember, our series of images is, in effect, divided into five groups of four.) The sequence number of the thumbnail tells us how much further down the set of images we need to count from the base number (mainCount) to reach the image we need to display in this thumbnail.
The next two lines bundle this information into the value of the String variable imgName, which we pass to imgRequest, just as we did in the Montage Engine.
Finally, we make a call to a sibling object called mainImage, telling it to load the image we've just specified. That statement causes the appearance of a second, full-size copy of the present thumbnail image in the main image block on the right side of the screen. Just what we wanted.
The last element we need to cover in imageClass is the getImage() custom method:
public function getImage():void
{
imgNum = MovieClip(root).mainCount + offsetCount;
imgName = "pix/img_"+imgNum+".jpg";
imgRequest = new URLRequest(imgName);
myLoader.load(imgRequest);
}
The similarity both to our code from the Montage Engine, and the onClick() method, should be apparent. Notice that we route the load request to myLoader, our local instance of Loader, instead of the loader on the mainImage object. That's because this method is meant to be called when the project loads, or the series of thumbnails is refreshed (hint).
VI. What's left to do
The bits and pieces we've detailed so far will set up the five visible elements on screen, and allow you to click on a thumbnail and see the full-size version at right. To finish the assignment, you need to add the two arrow buttons, and give them the necessary operations.
Here's a checklist:
- IN THE DOCUMENT CLASS, create two instances of buttonClass. While it may be tempting simply to add these instances in the Flash editor, if you do this, you will not earn the A-minus. USE CODE.
- If you look at the .fla file, you'll see that there is only one arrow, while the finished version requires two, one pointing left, the other right. Again, you may be tempted to use the editor to supply the missing element. However, if you set the scaleX property of an instance to -1, using code added to the document class, you'll accomplish the same purpose with less effort. Again, this is a requirement for the promised grade.
- Also in the document class, specify where these buttonClass instances appear on screen.
- Complete buttonClass, giving it the necessary functions. Clicking the right-pointing arrow should advance the group count (mainCount). Clicking the left-pointing arrow should do the reverse.
- Detect and manage limit cases, where mainCount is either greater than 4 or less than zero.
- Finally, add code to buttonClass to refresh the four thumbnails plus the main image display whenever you change the main count.
VII. Further enhancements
Here are some challenges you might attempt in order to move up to the full A:
Re-design the screen and the software functions to accommodate more thumbnails. This will probably necessitate expanding the image set as well.
Alternatively (or in addition), create a random jump button that flips to a particular group of thumbnails at random.
And finally, if you're looking for a somewhat larger challenge, re-design the project so that we move through the thumbnail set not four at a time, but one at a time, and handle end-of-sequence conditions appropriately.
VIII. Specifications
Make sure you upload the pix folder to the Lab3 subfolder in your personal account on student-iat.
Perform a Publish operation on your .fla file, and rename the resulting HTML file index.html. Edit the HTML page, adding a paragraph or two describing any features of your project of which you are especially proud. This step is crucial if you want something higher than the A-minus.
Upload the index page, and the AC_RunActiveContent.js file generated when you Publish, to Lab3.
Also upload your .swf file, your .fla file, and any .as files.
IX. Source files
In the lab03 folder in MULTIMEDIA on student-iat, you'll find three folders: pix, containing the 20 graphics used in this project; STARTER, containing the skeleton files and basic movie file; and GIVEN, which contains the first-level code described above, which we will build step-by-step in the lab.
|
|