|
The Flash movie at left allows you to specify a number of columns and rows for a grid, then generates a new browser window containing a .swf with the specified grid. This .swf redraws itself dynamically based on the size and shape of the browser window.
Download a variation on the .swf file here.
|
The Stage object was an addition to
your Actionscript arsenal with the release Flash MX. One terrific use for the
Stage object is to dynamically set the size and position
of objects in your Flash movie based on the size of the stage. Since we can
do this at runtime, we can dynamically alter the layout of our movies in response
to the user resizing the browser window. In this tutorial, I'm going to show
you how to utilize the Stage object to make your movies
responsive to the user's actions. We'll make two movies - one that repositions
movieclips and another that dynamically redraws itself, both in response to
user actions.
- The first movie we will make will reposition four boxes
based on the size and shape of the window. Open this
file to see it in action. You can download the sourcefile here.
To make you own, first create a new file named "resize.fla".
- Our movie requires only one asset. Make a 50x50px box
using the rectangle tool. Convert this into a movieclip (F8) with its registration
point in its center. Name this symbol "corner".
- Drop four instances of "corner" (including the one you
originally drew) on your stage, anywhere you'd like. Name the instances "tl",
"tr", "bl" and "br" (top left, top right, bottom left and bottom right). That's
it for graphic set-up. Now to the code!
- With the first and only frame selected, open your Actionscript
editor and type the following lines:
Stage.scaleMode = "noScale"; |
Stage.align = "TL"; |
Not too tough to start out, is it? (I'll let you in on a little secret -
it's not too tough the entire way through!)
The two lines of code above just set up our stage to act as we need it to
in order for our resizing to work. scaleMode and
align are two properties of the Stage
object in much the same way as _xscale and _alpha
are properties of the MovieClip object. scaleMode
tells our stage that it shouldn't scale at all once published -- this will
lock its dimensions. Next, we set the align to "TL"
or top left so that our Flash movie is aligned at the top left of our window.
Once these properties are set, we can get accurate readings for the width
and height of the stage.
- Add two more lines under the two you wrote above:
w = tl._width/2; |
h = tl._height/2; |
This should be nothing new. We store half of the width and height of our
corners in two separate variables (in case you wanted something other than
a perfect square). We will need these to position our corners with the knowledge
that their registration points are in the center of the box graphic.
- Can you believe we're nearly done? Add the following lines
to the code:
OK, so what are we doing here? To understand what's going on, and how it
will work, you need to understand what a listener is. You see, most objects
in Flash have built in methods (or handlers) that run when certain events
are fired. For instance, when a button is pressed, it automatically runs its
onPress handler. When it is then released, it runs
its onRelease handler. You could say that the button
is enabled to "hear" the pressing and releasing event whenever it is fired.
The same is true for movieclips as they "hear" when a frame is entered and
so run their onEnterFrame handler. Well, when the
stage is resized, another event is fired -- let's call it "resize". Problem
is, there are no objects that are enabled to "hear" this event. But! All is
not lost! We can add listeners to the Stage object
so that they can "hear" when the resize event is fired. This is what we do
in the above line of code - we enable the main timeline (this)
to "hear" the Stage's events. Now all we need is
to set up a handler to run when the resize event is fired. Next step!
- End of the line! Add the following lines to the code in
the Actionscript editor to finish up:
this.onResize = function() { |
|
|
|
tr._x = br._x = Stage.width
- w; |
|
|
bl._y = br._y = Stage.height
- h; |
|
}; |
That's it! Whenever the stage is resized, the main timeline will run its
onResize handler (this should always be named onResize,
by the way). It then repositions the four corners based on the Stage.width
and Stage.height - two additional properties of
the Stage object.
- To see this work, publish your .swf with an HTML file
with the following settings in the File>Publish Settings window. Then open
the HTML file in a browser and see the dynamic repositioning in action.
That's a quick sample of how to put together a movie that will reposition its internal elements based on the stage size. Let's take it a step further and create a gridded movie that redraws based on the stage size and shape. The example above illustrates this. You can download a modified sourcefile here.
- Create a new Flash file named "resizableWindows.fla". This file will need nothing in its library nor nothing on its stage. It's all code, baby!
- Select the first and only frame in the movie, open your Actionscript editor, and start the code rolling:
Stage.scaleMode = "noScale"; |
Stage.align = "TL"; |
Stage.addListener(this); |
Nothing new here, let's keep it moving ("Nothing to see, people!").
- We're now going to add some variables to the top of our code that will set the look of our movie:
columns = [0, .15, .25, .95, 1]; |
rows = [0, .25, .5, 1]; |
|
borderThickness = 3; |
borderColor = 0x3F3754; |
fillColor = 0xC1A1FF; |
The first two variables control the number of rows and columns in our grid, and the size of each one. To make it easier later on (though it might seem unintuitive here), the numbers in the columns and rows arrays specify the start and ending percentages (out of 1) of each column or row. So the first column goes from 0-15%, the second goes from 15-25%, etc. The thickness and color variables set the colors of our grid.
- This next bit of code is just a function to draw a rectangle
using the drawing API. Add it next.
drawBox = function(pt, w, h) { |
|
|
|
|
lineTo(pt.x + w, pt.y + h); |
|
|
|
|
} |
We will send the drawBox() function three parameters:
the point of the top left corner of a rectangle and the width and height of
the rectangle. Using these, we use the drawing API commands moveTo()
and lineTo() to draw the rectangle. We will call
this function for each section of our grid.
- Almost there! We have previously enabled the main timeline
(this) to "hear" Stage
events, so now we need to write a function for onResize
that will redraw our grid whenever the stage size and shape are changed. Let's
start it like this (you can place this at the end of all of our previous code):
this.onResize = function() { |
|
|
|
|
|
lineStyle(borderThickness, borderColor, 100); |
|
|
} |
This doesn't do anything as of yet, but will serve as the bookends of our
onResize. All we do so far is store the current
stage height and width in variables and clear all graphics in our main timeline.
After clearing the stage, we need to reset our lineStyle
based on our variables above (when you clear a movieclip, its lineStyle
is automatically reset).
- Last bit of code, but it's a doozy! We will now loop through
each row and column and draw a rectangle of the appropriate size. Since a
grid is two dimensions, we will use nested for loops
to run through both rows AND columns. Add the lines in bold:
this.onResize = function() { |
|
|
|
|
|
lineStyle(borderThickness, borderColor, 100); |
|
|
for (var i = 0; i < rows.length-1; i++) { |
|
|
for (var j = 0; j < columns.length-1; j++) { |
|
|
|
|
var bW = w * (columns[j+1] - columns[j]); |
|
|
var bH = h * (rows[i+1] - rows[i]); |
|
|
beginFill(fillColor, 100); |
|
|
drawBox({x:x, y:y}, bW, bH); |
|
|
|
|
|
} |
Breaking this down, the first for loop runs through each row, then the second runs through each column in that row. The top left corner for the particular section of the grid is then calculated and stored in the x and y variables. Next, the width and the height of the grid section is calcluated and stored in variables as well. Once all of this information is determined, we draw a solid rectangle for that section.
- Once again, to see this in action publish an HTML page
and a .swf file, then open it inside a browser. Alter the values we set at
the top of the code to change the look. Try adding or removing columns and
rows as well as changing their sizes. Resize the browser window to see the
stage redraw itself. Nice!
That's all it takes! Using the Stage
object to check on the size and shape of Flash window, you can now create more
responsive interfaces that react to user actions. One way I have utilized this
at 27Bobs is to set the maximum and minimum sizes for my Website. Although the
user can scale the browser up and down, I have limited the scaling of the Flash
movie embedded in the window so that things never get too small (illegible)
or too large (too processor-intensive). That's one use, but there are many more.
Now that you know how to code it, go and find those other uses! Explore and
enjoy!