Back to Entry Page

Anatomy of the Flash panorama project ("undersea")

flash panorama project

Concept

This project demonstrates a seamless, 360-degree visual panorama with text overlays coordinated to currently visible content. It also shows how to use keyboard input as a form of interaction. As in the case of the dynamic mask example, the scripts are relatively simple; most of the important tricks lie in the design and geometry of this project.

The source file for this project, undersea.fla is available on Crow at multimediaShare/undersea.

Setting up the panorama graphic

A panoramic image contains all the visual information available in a full, 360-degree rotation around a given viewpoint. The example used in this project was generated from a Bryce 4 model, but you can create photographic panoramas in real space by mounting a camera on a tripod or other flat, stable platform and taking several pictures at regular rotations. The number of images depends on the focal angle of your camera, but eight images shot at 45-degree rotations usually do the trick. (Disable your camera's autofocus feature, if it has one.)

You can create a composite or "stitched" panorama from your separate shots simply by arranging them in Photoshop or some other image processor; or you can use a specialized program to help you blend and stitch. Some of these programs may be downloaded as shareware. Two of the better examples, Apple's QuickTimeVR Authoring Studio and PictureWorks' SpinPanorama, can be made available in the Hypermedia Room on request.

the panorama image from the 'undersea' project, reduced

Creating a panoramic graphic is only the first step, however. You need to make a crucial modification before you can use the graphic in a Flash panorama. The image above is divided into three regions marked a, b, and c. The a and c regions are shaded in red here for better visibility; they don't look that way in the actual image.

The original stitched panorama consisted only of a and b. If you look closely, you'll see that the region marked c is actually a duplicate of the a region. This section of the image was added to provide a buffer so that the panorama can scroll seamlessly from beginning to end and back again. I'll explain more about the function of this buffer below.

For the moment, simply note that you must repeat a certain portion of the initial panoramic image. The width of this repeated section is very important: it is equivalent to the width of the window in which the movie will operate. In this case, that window is 600 pixels. If it had been something less than that, the repeated section would have been correspondingly smaller.

Flash architecture

The panoramic function of this movie requires only a single frame in a single layer--as you might guess, all the heavy lifting is done with ActionScript. (Actually the project contains a few more layers, but these support other functions.)

That single frame contains a movie clip which in turn contains the modified panoramic image discussed above. You may wonder why it's necessary to install the image within a movie clip; why not simply use the image as a symbol? We must introduce a movie clip because we'll be using keyboard events to control the behavior of the panorama. Only an onClipEvent() handler gives us access to keyboard events, and obviously, only movie clips can use this handler.

The script for this project makes two assumptions about positioning, one about the image within the movie clip, the other about the movie clip within the visible area on the main timeline.

We assume that the panorama image is aligned within its clip (called panoClip) so that the entire graphic falls to the right of the registration point (indicated by the crosshairs). We also assume that the image is centered vertically on the crosshairs. If this description is not clear to you, open undersea.fla and have a look at the clip panoClip within it.

The script for this project further assumes that panoClip is aligned so that its left edge coincides with the left edge of the visible area in the main timeline--that is, the clip's X and Y coordinates are both zero.

You could make different assumptions about the position of the pano image within its clip, or about the position of the clip, but you'd then have to change the limit values used in the animation script.

Scripting the pan effect

To accomplish uninterrupted scrolling, its necessary to use keyboard rather than mouse events. Unfortunately, mouse events in Flash are discrete: once there's been a mouseDown, there must be a mouseUp before mouseDown can happen again. Keyboard events don't work this way. The keyDown event continues for as long as any key is pressed.

Here's what we do with this very useful property. The following script is attached to the panoMovie clip in its lone frame.

onClipEvent(keyDown)
{
  whichKey = Key.getAscii();
  
  if(whichKey == 97)
    {
      this._x -=25;
      if(this._x < -2175) this._x = 0;
    }

  if(whichKey == 39)
    {
      this._x +=25;
      if(this._x > 0) this._x = -2175;
    }
 }

The Key object (note that capital K) is a built-in feature of Flash that records information about the keyboard. Among other things, it can give us back a numerical code or ASCII value that identifies which key has been pressed. The script as written responds to two values: lowercase a (ASCII 97) and apostrophe or ' (ASCII 39). These keys happen to be the leftmost and rightmost ASCII characters in the home row of the keyboard.

We use the variable whichKey to store these ASCII values, and execute one set of statements for lefthand movement when the leftmost key is pressed, another for righthand movement when the rightmost key is pressed.

Now we come to the contents of the left and right movement conditions. The statements that add and subtract to/from the current X position should require no comment. The if tests that follow in each case take a bit more explaining. The numbers represent limits on movement: points at which the pano must loop back on itself. But how do we arrive at those magic numbers?

The pano image we're using for this project is 2800 pixels wide. But remember that the last 600 pixels of this image repeat the first 600 pixels, so the unique content of the image is really only 2200 pixels wide.

That figure of 2200--actually -2200--is crucial, because we know that when the movie clip that contains the image has moved 2200 pixels to the left (into negative numbers, since it's moving by subtraction), the righthand edge of the image has reached the left edge of the visible window. At that point we have to do something, or else we'll run out of image to display; so we reposition the panorama movie clip at X=0, which does the trick.

But this fast shuffle works only because of that extra 600 pixel buffer we added on when we built the panoramic image. That repeated content at the tail end of the pano fills up just enough screen space to keep any gap from being visible as we scroll toward the limit point.

Now, about that limit point. You may have noticed that the magic number in our discussion above is -2200, but the script actually uses a different value, -2175. This is because the script moves the pano clip in 25-pixel increments. If it only moved one pixel at a time, we could safely use the actual limit, -2200; though then the action would crawl along horribly. So we do a little adjusting.

Let's say you want to reconfigure undersea.fla using an image of different width. You can calculate the leftward limit for an image of any size in the following way:

  • Subtract the width of your visible window (in this case, 600) from the overall width of your panoramic image (in this case, 2800); this gives you the width of your unique visual content (in this case, 2200).

  • Multiply that number by -1, because when you move the pano clip left from zero, its X coordinate will be a negative number; here, this gives us -2200;

  • Adjust this raw limit by the amount of change in each iteration of the script (in this case, 25 pixels, which when added to -2200 gives us -2175);

Rightward motion is easier to handle because its limit point is always zero. You don't need to worry about adjusting this value by the amount of the movement, because we never actually move into positive territory; as soon as the pano clip threatens to do that, we pop it back to X=-2175, which is to say, we return it to the lefthand margin of the visible space. The magic number -2175 will of course differ if you use a differently sized image, but this number will always correspond to the number you use to limit leftward movement.

You now know everything there is to know about simple, horizontal panoramic image browsing.

Text overlays

The undersea project adds a feature to the panoramic movement. Text appears in an overlaid window as you scroll through the image. The text changes depending on what objects are in view.

We won't go into the detail about this effect (though the scripting is contained in the undersea.fla source file), because the principle is very simple. A function is invoked at the beginning of the keyDown handler. This function compares the current X position of the pano clip to several ranges expressed as if statements. If the current X falls within one of these ranges, the appropriate text is inserted into the display field.

Flash versus QuickTimeVR

This project could have been built using Apple's QuickTimeVR and delivered as a QuickTime movie (.mov) instead of a Flash movie (.swf). QuickTime supports smooth, dynamic pans, actually in both X and Y axes. It also supports hotspots and rollovers keyed to specific regions of a panoramic graphic.

However, while it is arguably easier to build basic panoramas in QTVR than it is in Flash, adding rollover text requires expert knowledge of QuickTime's scripting language, which at the moment seems even rougher and less ready than ActionScript. The current version of Apple's QTVR authoring tool (QuickTimeVR Authoring Studio 1.0) only handles hotspots, not rollovers.

Arrow keys?

You may be wondering why we chose the a key to control left movement and the apostrophe for right, instead of using the arrow keys that come standard on just about every keyboard. In fact earlier versions of this project did use the arrow keys. They worked just fine in Netscape Navigator but would not work at all in Internet Explorer, either because Microsoft reserves the arrow keys exclusively for browser functions, or because the folks who developed the MSIE version of the Shockwave plug-in forgot to include code to control the arrow keys.

Whatever the reason, the arrow keys appear to be off-limits, unless somebody can come up with a fix.


University of Baltimore Logo

Copyright © 2002 School of Information Arts and Technologies