Vertical Stretch Menu
A SWiSHmax Project
By Jim Helton
For 13dots.com
I’ve always been impressed by the fancy menus that people create with Flash, so when a 13dots member asked for a tutorial to create a stretch menu in SWiSHmax, I jumped at the opportunity. The following project (a rather long tutorial actually) will show you the method that I used, and will detail some considerations to keep in mind when adapting it for your use. Here's what we are going to create:
Planning Your Menu
The stretch menu is really several drop-down menus that are stacked on top of each other. When not active a menu is hidden behind the menu header, so you need to decide how many menus will be included and the submenus attached to each. For this project I will be creating 3 menus with 4 submenus each.
CONSIDERATION: If you will be using images for menu items, it’s important that you have an idea of what order things will be in, and that
you size the items appropriately.
Getting Started
For the project I’m going to start with a 100 x 400 movie, but don’t worry too much about the size just yet, we will adjust later. Even though I’m
not using any canned effects on the timeline, the frame rate still has an effect on this menu. I’ll be using 30fps for a smooth effect that is not
overly fast. Once you complete yours, play around with the frame rate to find what looks best to you.
So here is what we are working with:

Now let's make a menu!
Part 1 – Make a single drop down menu
Create a rectangle that is large enough to cover your submenu items. Be sure to leave some space on either side and the top (we’ll be using that
space later).

IMPORTANT: Make sure that your Anchor point in the Transform properties panel is set to Top left for all of the objects you are creating.
Then add your submenus below it, making sure they are smaller than the menu, which they will hide behind. You should now have something like this:

While we’ve got the menu laid out, let’s add the text and any other decorations to the menu and submenu.

Get it straight!
If your Submenus are not lined up straight already, then select all of your objects and click the Align Horizontal Center button on the Align tab.

Once you have everything looking the way you want it, it’s time to start grouping everything. First, we need to get everything in order in the
Outline. Drag your objects so that the Menu is at the top, followed by the Submenus in order. Put your text on top of the menu item they belong to
in the Outline. Our Outline should look like this now:

To make rollover effects easy for your Submenus we’ll group them as buttons and give them a separate over state. To do this, select your Submenu
in the Outline and then hold down Ctrl and click the associated text. With both objects selected right click on them and choose Grouping\Group as
Button.

On the Button properties tab click the Has separate over state.
Group the remaining Submenus. You DO NOT have to group the menu cover as a button. With all of the buttons expanded your Outline should look like
this now:

NOTE: I prefer to give my objects meaningful names so that I can find them quickly. I don’t detail how to name the objects for the sake of
the tutorial size (big enough as it is), so use your preferred naming scheme or follow mine. I’ll mention when it’s important to name objects.
You can now set your button effects. I’m adding a color change to the over state by changing the Submenu object to grey for each button’s Over
State. The last item is to add a getURL function to each button (it is a menu after all!).
Select the Submenu button in the Outline and switch to the Script tab in the workspace. Switch to Guided mode if you aren’t already there and
click Add Script\Browser/Network\getURL(…).

You can now set the URL for this Submenu by entering the full URL in the options window. Set the Window option to your liking and leave Variables
on Don’t send.
You should now have this for your button script:

NOTE: Depending on the viewer’s security settings for Flash, if you specify a URL that goes to a different domain name than where your menu
is hosted it may be blocked. It’s best to use relational URLs for navigation within the same site. For example, if your menu is used in
http://www.mydomain.com/index.html and you want to link to
http://www.mydomain.com/coolstuff.html then just put coolstuff.html in the URL field
for your button.
Repeat this step for each button.
Time to group your groups…
To be able to properly reference the components of your Menus and setup the movement effects scripts, we need to group everything into a sprite,
and each Submenu button into its own sprite. To do this right click each Submenu button and select Grouping/Group as Sprite.

IMPORTANT: Because we will be referencing these objects in the scripting it’s important that they each have a unique name. Therefore, I’ll
be naming each Submenu sprite as follows:

One more group…
To keep the Menus separate from each other, and to allow us to make them move we need to group all of the objects in our drop down menu in one
sprite. Click on the first object, then shift-click the last item to highlight them all. Right click the selected items and choose Grouping/Group
as Sprite.
IMPORTANT: Just as we did with the Submenus, we must give our main sprite a unique name. Let’s call it Menu1. Your Outline should now look
like this:

Time for some scripting! (finally)
To keep track of which Menu is active, we’ll need a variable. We’ll put it at the scene level. To do this, select the scene in the Outline and
click the Script tab in the workspace. Switch to Expert mode and add the following script:
CODE
onload () {
ActiveMenu="none";
}
This will initialize the ActiveMenu variable at load and give it a value of “none”.
TIP: If you wanted one of the menus to be expanded by default you could set the value to your default menu.
So you should now have the following:

Next we’ll add the movement script. Select the Menu1 sprite in the Outline and in the script window add the following script:
CODE
onEnterFrame() {
if (_root.ActiveMenu=="Menu1") {
spSubmenu1._y -= 170;
spSubmenu1._y *= .6;
spSubmenu1._y += 170;
spSubmenu2._y = (spSubmenu1._y + spSubmenu1._height + 1);
spSubmenu3._y = (spSubmenu2._y + spSubmenu2._height + 1);
spSubmenu4._y = (spSubmenu3._y + spSubmenu3._height + 1);
} else {
spSubmenu1._y -= 5;
spSubmenu1._y *= .6;
spSubmenu1._y += 5;
spSubmenu2._y = spSubmenu1._y;
spSubmenu3._y = spSubmenu1._y;
spSubmenu4._y = spSubmenu1._y;
}
}
What the script does
onEnterFrame() {
By putting this event handler in the script with no frame defined it defaults to the first frame (1). Because we do not specify any other events
at later frames, the Flash Player will look at this frame at each frame per second (fps) interval, which creates a legal (but not really clean)
infinite loop. It is the engine that drives the following processes.
if (_root.ActiveMenu=="Menu1") {
Here we are checking the variable we setup in the _root object (Scene_1 in this case) and if this menu is active we execute the actions to expand
the menu (see below).
spSubmenu1._y -= 170;
spSubmenu1._y *= .6;
spSubmenu1._y += 170;
These lines manipulate the position of the spSubmenu1 object (the sprite containing our Submenu1 button). This may look a little confusing if you
haven’t seen this process before, so I’ll break it down for those who want to understand it (feel free to skip the next section if you aren’t in
the mood to geek out).
GEEKMODE: ON
_y represents the Y coordinate of the spSubmenu1 sprite as determined by the anchor point specified in the Transform properties panel for our
object.
In my example, the Y coordinate starts at 5 because when the movie loads the menu is set to inactive and moves to the Y coordinate specified in
the second part of the script. Note that the coordinates are relative the sprite they are contain in, not the scene that contains them.
When the menu becomes active, based on the if condition, the script begins to evaluate these statements on each loop iteration.
So let’s do the math for the first iteration:
5-170 = -165
-165 * .6 = -99
-99 + 170 = 71
Which moves the spSubmenu1 sprite object down to Y coordinate 71 on the first iteration. It then loops and does it again:
71-170=-99
-99*.6=-59.4
-59.4+170=110.6
Which move the spSubmenu1 sprite object down to Y coordinate 110.6 on the second iteration. Note that on the first iteration we moved down 66
pixels, and on the second we only moved 39.6 pixels down. This continues through the process and is what gives us an easing effect. If you
continue to do the math for each iteration you will get:
134.36
148.616
157.1696
162.30176
165.381056
167.2286336
168.33718016
169.002308096
169.4013848576
169.64083091456
At this point the sprite has moved as far as it’s going to. Because these numbers relate to pixels, and you can’t move a fraction of a pixel,
Flash is actually rounding these numbers, so 169.6=170. Keep in mind that Flash does not stop doing the math when your object gets to its
destination, so having numerous loops of this type active in your script may become resource intensive. However, only having several active should
not cause any noticeable issues.
GEEKMODE: OFF
Continuing code explanation
spSubmenu2._y = (spSubmenu1._y + spSubmenu1._height + 1);
spSubmenu3._y = (spSubmenu2._y + spSubmenu2._height + 1);
spSubmenu4._y = (spSubmenu3._y + spSubmenu3._height + 1);
These lines position the remaining Submenu sprites relative to the first, which is now in motion thanks to all that complicated math above! If you
want to understand how it works see the following GEEKMODE section, otherwise feel free to skip to the next section.
GEEKMODE: ON
spSubmenu2._y sets the Y coordinate for the spSubmenu2 sprite that contains our second Submenu button. The value is determined by taking the Y
coordinate of the sprite above it (spSubmenu1._y), adding to it the height of that sprite (spSubmenu1._height), then adding 1. Based on the math
detailed above, in our example the actual math for the first loop iteration looks like this:
spSubmenu2._y = (71+20+1) or 92
This is repeated for each subsequent sprite (spSubmenu3, spSubmenu4) in our menu. The resulting effect is that when our Menu becomes active all of
the Submenu items below the first will jump instantly into place below the first Submenu. They will then move down at the rate of the first
Submenu and stay 1 pixel apart. This is great because it means that the Submenu objects don’t have to be the same size, and no matter what the
size, they will always stay apart and move relative to each other.
GEEKMODE: OFF
Continuing code explanation
} else {
What to do if this Menu is not active.
spSubmenu1._y -= 5;
spSubmenu1._y *= .6;
spSubmenu1._y += 5;
These lines do the same thing as the process above, except move the spSubmenu1 sprite to its location when the Menu is not active. (No need to
geek out twice in one tutorial for the same stuff…if you skipped it the first time and just now got curious just scroll back up).
spSubmenu2._y = spSubmenu1._y;
spSubmenu3._y = spSubmenu1._y;
spSubmenu4._y = spSubmenu1._y;
Here we are simply putting all of the sprites below spSubmenu1 at the same Y coordinate as spSubmenu1. The result is that when the Menu becomes
inactive all of the Submenu objects snap together and move behind the Menu cover.
That’s it! Simple right?
If you play your movie now all off the Submenus should pull up under the Menu object. So let’s add the event that will activate the menu.
In the Outline select the Menu object (in my example it would be Menu1Cover) and click the Script tab in the workspace. Switch to Expert mode and
add the following script:
CODE
on (rollOver) {
_root.ActiveMenu="Menu1";
}
This causes the menu to become active when you mouse over the Menu.
Your script should now look like this:

Now if you play your movie the Submenu objects should hide under the Menu. If you move your mouse over the Menu object the Submenu objects will
expand below the menu. In the case of my example they jump way to far below the menu. So it’s time to tweak the menu.
Figure out the correct drop down distance
The easiest way to find the right distance for your drop down is to start with the height of the Menu object and then just add or subtract from
that number under you are satisfied with look of the menu. Do this by adjusting the number (we started at 170) in the script on the Menu1 sprite.
You may have to play, test, adjust, test again several times until you get it right.
Add a bounding box to make testing easier
As you found out when testing for the drop down distance, your menu current has no way to deactivate. To fix this we’ll add our first bounding
box, which will allow us to deactivate the menu during testing.
In the Outline select Scene_1 and switch to the Layout tab in the workspace if you aren’t already there. Select the Rectangle tool and draw a box
across the top of the scene above your Menu1 object. It’s OK if it goes outside of the movie, but it should not cover any part of the Menu1
object. Zoom in and adjust if necessary. You should now have the following:

Once your rectangle is adjusted set the fill and line to none. To keep things tidy in the Outline drag the Shape to the bottom of the list. With
the shape selected switch to the Script tab in the workspace. Switch to Expert mode and add the following script:
CODE
on(rollOver) {
_root.ActiveMenu="none";
}
This will cause our menu to become inactive when the mouse passes over the bounding box. You should now have the following:

If you test your movie now you should be able to mouse over the Menu and have it drop down. If you then pass your mouse over the top of the movie
where the bounding box was added the menu should collapse.
We’re almost there! Let’s add some more drop down menus.
First, let’s clean up just a bit. If your Submenus are positioned below the Menu object in your scene when editing we can move them under the Menu
object by changing their Y: value to 5. Do this by selecting them in the Outline and changing the Y: value in the Transform properties tab.
Your workspace should now look like this:

At this point you have 2 options for adding additional menus. If you are going to use the same shapes for the additional menus, then the fastest
way is to copy and past the Menu1 item into the scene as many times as you need. If you are using various different shapes, or images, for your
menu items, then you can repeat the previous steps to create the additional Menus that will make up the stretch menu.
For the example I’m going to cut and paste, so collapse the Menu1 sprite in the Outline panel then right-click it and choose Copy Object.
Right-click Scene_1 and choose Paste in Place. Now right-click Scene_1 again and choose Paste in Place again to add the 3rd menu.
Move the new menus down in the workspace and rename them to Menu2 and Menu3 respectively. If you use the arrow keys to move the menus they should
remain lined up. If you drag them with the mouse and they get out of line, just select them all in the Outline panel and then use the Align
Horizontal Center button on the Align properties tab. Next drag them into order in the Outline. You should now have the following:

Finally, I’m going to expand the new menu sprites and update the text and object names so that they relate to the new menus. We also need to
update the scripts and change the activations and conditions to reflect the proper menu name.
IMPORTANT: You must change the script on the Menu object (MenuXCover in my example) to change the _root.ActiveMenu variable to equal the
menu name and then update the if condition on the menu sprite (MenuX in my example) so that when the _root.ActiveMenu variable equals the menu
name. Otherwise all of the menus would expand when you pass the mouse over any of the Menu objects! (Wouldn’t that be messy!!). For example, here
are the scripts for Menu3:

And

So now if you test your movie each menu should expand individually (over top of the menu below it) and all of them should collapse if you pass
your mouse over the bounding box at the top of the scene. Note that only one menu will be open at a time because passing over a Menu object
changes the ActiveMenu variable to that menu, and therefore deactivates the previously active menu.
Let’s add the stretch…
In the Outline panel select the Menu2 sprite and switch to the Script tab in the workspace. Change to Expert mode and add the following line after
the
onEnterFrame() { line:
CODE
this._y = (_parent.Menu1._y + _parent.Menu1._height + 1);
This will set the Menu2 position to be relative to the position of Menu1 in the same way that we did earlier for the Submenu objects. Your script
should now look like this:

NOTE: The internal player in SWiSHmax does not properly parse the relative object pathing (_parent.Menu1) from within the sprite. If you
try to play the movie it will return an error that it cannot find the variable Menu1. From this point on you will need to use the File/Test/In
Player (Ctrl+T) for playing the movie.
Now add the following line to the Menu3 sprite after the
onEnterFrame() { line:
CODE
this._y = (_parent.Menu2._y + _parent.Menu2._height + 1);
This makes Menu3 relative to Menu2.
Now test it in the Player and you should have a stretch menu! FINALLY! Just a few finishing touches and we’re all set.
Polish up your distance settings. As I began to add the stretch code to the menus I realized that the text box on my menu objects was larger than
the rectangle, so I had to resize it to be inside the rectangle. Otherwise, when my menus were collapsed I had to have a negative adjustment, but
that caused problems when the menu expanded. I also noticed in the player that my submenus where peaking out at the bottom, so I adjusted the
deactivated position from 5 to 3. The last adjustment was for the dropdown distance, which in the player caused too much of a gap between the
submenus and the menu, so I changed the Y location from 29 to 26.
Adjust the menu speed. I noticed as I was doing my final testing that the menu was a bit too snappy. To really get a stretch effect you want to be
able to see the easing when switching between the menus. There are two ways to change the speed. The first is to adjust the easing rate. In the
case of my menu I change the .6 to .8 and that did the trick. Unfortunately you cannot set this number above .9 or it won’t work. Another way to
adjust the speed would be to reduce the frame rate, just remember that you will trade quality for performance if you lower the frame rate too
much. Play with it and you’ll see what I mean.
Resize the movie size. Based on the distance that my menus stretch, I didn’t need the full 400 pixel height that I started with. By dragging the
movie size up and testing I was able to reduce the height to 180 (leaving a bit of room for the last step).
Add the remaining bounding boxes. Copy the bounding box that you created at the top of the scene and paste 3 copies. Then resize them so that you
have a box on each side of menu. Set the fill to a solid color to help position them and then set it back to none when you finish. Make sure the
bottom box only covers the space between the bottom of the stretched menu and the bottom of the scene. You may have to test a few times to get it
just right, but you don’t want it to overlap the stretched menu or it will cause the menu to collapse when you mouse over it. Your movie should
now look like this:

NOTE: I’ve left the color in the bounding boxes so they are visible to give you a look at the final size and position.
Final thoughts…
What an adventure figuring this out was! In the end it’s a very cool concept that looks sharp. The one weakness of this menu is the need for the
bounding boxes. If the menu is expanded and you move your mouse off of the movie to fast to register on a bounding box it remains expanded.
Because of this I’d suggest making them as large as possible without interfering with your layout (provided it’s used on an HTML webpage).
With a little creativity this concept could be adapted to a lot of different uses. Don’t be afraid to experiment and see what you can come up
with!
And the source...
stretchmenu.swi ( 56.19K )
Number of downloads: 7849