Menu with ActionScript 3
February 17, 2009 by: smonteThis tutorial will show you how to create a cool scrolling menu with ActionScript 3! We will animate the menu as the user hovers over it. Give it a test run and tell me what you think!
Note: You need TweenMax to fully complete this tutorial.
Setting up the environment
1. Create a new Flash document of size 300×300.
2. First, let’s draw a menu item. Create a rectangle of size 200×25 without any stroke. Use a fill color of #16222E.
3. Convert the rectangle to a movie clip named “Menu Item“. Set the registration point to the top left corner.
4. Inside the movie clip, create a new new layer. Add a dynamic text field in the left side of the menu item. Type some text in it (make the text field long enough!).
5. Give the dynamic text field an instance name of “itemText“.
6. Next, convert the fill color (the rectangle) to a movie clip. The rectangle should be in the first frame of the movie clip. Name it “Fill“. Registration point doesn’t matter.
7. Give the “Fill” movie clip an instance name of “itemFill“.
8. Go back to the main timeline. Linkage the “Menu Item” movie clip to a class named “MenuItem“. If are are unfamiliar with movie clip linkage, please see step 4 in the External Classes tutorial.
9. Remove the menu item movie clip from the stage.
10. Now we will draw the mask for our menu. Create a rectangle with rounded corners of 10 without any stroke. Make the rectangle of size 200×250. You can use any fill color since this will be a mask.
11. Convert the rectangle to a movie clip. Name it “My Mask” and set the registration point to the top left corner.
12. Give the mask movie clip an instance name of “myMask“. Position it to the center of the stage. Your stage should now look similar to this.
Moving to ActionScript
13. Create a new layer for ActionScript and type the following.
//Import TweenMax and activate tint plugin import gs.*; import gs.plugins.*; TweenPlugin.activate([AutoAlphaPlugin,TintPlugin]); //Set how many menu items we will have const NUMBER_OF_ITEMS:Number = 20; //Save the mask's height var MASK_HEIGHT:Number = myMask.height; //This movie clip will contain all the items var menuHolder:MovieClip = new MovieClip(); //Position the menu holder to the same place where the mask is menuHolder.x = myMask.x; menuHolder.y = myMask.y; //Add the menuHolder to the stage addChild(menuHolder); //We want to know when the mouse is over the menuHolder var mouseIsOver:Boolean = false; //We want to know the previous y coordinate of the menuHolder for the animation var oldY:Number = menuHolder.y; //Set the mask for menuHolder menuHolder.mask = myMask; //Create the MenuItems for the menu. //Feel free to change the NUMBER_OF_ITEMS to what you want! for (var i=0; i < NUMBER_OF_ITEMS; i++) { //Create a new MenuItem var menuItem:MenuItem = new MenuItem(); //Position the item. //We will position the items from top to dowm. menuItem.x = 0; menuItem.y = i * menuItem.height; //Set the text for the menuItem menuItem.itemText.text = "Menu item " + (i+1).toString(); //We don't want the text field to catch mouse events menuItem.mouseChildren = false; //Make the item look like a button (handcursor on hover) menuItem.buttonMode = true; //We want to listen when the mouse is over and out of the item menuItem.addEventListener(MouseEvent.MOUSE_OVER, mouseOverItem); menuItem.addEventListener(MouseEvent.MOUSE_OUT, mouseOutItem); //Add the menuItem to the menuHolder menuHolder.addChild(menuItem); } //Save the menuHolder's height now that all the items have been added to it var HOLDER_HEIGHT:Number = menuHolder.height; //Add a listener when the mouse is over and out of the menuHolder menuHolder.addEventListener(MouseEvent.MOUSE_OVER, mouseOverMenu); menuHolder.addEventListener(MouseEvent.MOUSE_OUT, mouseOutMenu); //Add ENTER_FRAME for the menu animation addEventListener(Event.ENTER_FRAME, enterFrameHandler); //This function is called when the mouse is over the menu function mouseOverMenu(e:Event):void { mouseIsOver = true; } //This function is called when the mouse is out of the menu function mouseOutMenu(e:Event):void { mouseIsOver = false; } //This function is called when the mouse is over an item function mouseOverItem(e:Event):void { //Save the item to a local variable var item:MenuItem = e.target as MenuItem; //Tween the item's fill color. TweenMax.to(item.itemFill, 0.01, {tint: 0xff8800}); } //This function is called when mouse moves out of the item function mouseOutItem(e:Event):void { //Save the item to a local variable var item:MenuItem = e.target as MenuItem; //Tween the fill color to original state TweenMax.to(item.itemFill, 0.5, {tint: 0x16222E}); } //This function is called in each frame function enterFrameHandler(e:Event):void { //Check if the mouse is over the menu if (mouseIsOver) { //Calculate the vertical distance of how far the mouse is from //the top of the mask. var distance:Number = mouseY - myMask.y; //Calculate the distance in percentages var percentage:Number = distance / MASK_HEIGHT; //Save the holder's old y coordinate oldY = menuHolder.y; //Calculate a new y target coordinate for the menuHolder. //We subtract the mask's height from the menuHolder. //Otherwise the menuHolder would move too far up when the mouse is at bottom. //Remove the subraction to see for yourself! var targetY:Number = -((HOLDER_HEIGHT - MASK_HEIGHT) * percentage) + myMask.y; //Tween the menuHolder to the target coordinate TweenMax.to(menuHolder, 0.4, {y: Math.round(targetY)}); } }
14. You are done, test your movie! Remember, if you have any questions, feel free to visit the forum.
Related tutorials:
This is fantastic menu and very easy to manipulate, congratulations. I have a question: when i click a specified button how we can call another xml and generate new menuItems?
Thanks in advanced.
really great!..
Does anyone know how to input a specific name for each of the menu items? Like: home, forum, about and so on?
Great menu by the way
this is nice
Hello
Cool Tutorial, but i an error: Syntax error on line 7 (const NUMBER_OF_ITEMS:Number = 20;)
how i know there are no errors
who can mail me pls an tutorial that works???
thanx in advance
Adrian
How can I add functionality for these buttons??
Sorry for noob question but i am beginner:)
Please help
great tut. Thanks
I receive this error and I can’t figure it out. I have created all instances and linkages but receive this error:
TypeError: Error #1010: A term is undefined and has no properties.
at coolMenu_fla::MainTimeline/frame1()
Did I make a mistake at the time line or at the stage?
Hi, great tutorial! I was wondering how one would create unique button names for the menu items? Also, how would you create unique functions for these individual buttons? If thats too much to ask, I understand.
-jonathan
I restructured the code to allow for loading the menu itesm from an XML file.
Also added a click (mouse down) event to perform a URLRequest to link to the web page.
//Import TweenMax and activate tint plugin
import gs.*;
import gs.plugins.*;
TweenPlugin.activate([AutoAlphaPlugin,TintPlugin]);
//Set how many menu items we will have
const NUMBER_OF_ITEMS:Number = 20;
//Save the mask’s height
var MASK_HEIGHT:Number = myMask.height;
//This movie clip will contain all the items
var menuHolder:MovieClip = new MovieClip();
//Position the menu holder to the same place where the mask is
menuHolder.x = myMask.x;
menuHolder.y = myMask.y;
//Add the menuHolder to the stage
addChild(menuHolder);
//We want to know when the mouse is over the menuHolder
var mouseIsOver:Boolean = false;
//We want to know the previous y coordinate of the menuHolder for the animation
var oldY:Number = menuHolder.y;
//Set the mask for menuHolder
menuHolder.mask = myMask;
var HOLDER_HEIGHT:Number;
// 3/19/2009 customization 01 to get menu items from XML file
var sXMLfile:String ;
var xmlFilePath:String;
var xml:XML;
var nbrOfMenuItems:Number;
var aMenuURLs:Array;
var lblText:String;
//sXMLfile= getSwfParam(”XMLfile”, “CSReps.xml”); // later will get from a swf param
sXMLfile = “coolmenu.xml”;
xmlFilePath = sXMLfile;
var loader:URLLoader;
loader = new URLLoader();
loader.load(new URLRequest(xmlFilePath));
loader.addEventListener(Event.COMPLETE, xmlLoaded);
//addMenuItems();
function xmlLoaded(e:Event):void {
xml = new XML(loader.data);
xml.ignoreWhitespace = true;
loadMenuItems();
addListeners();
}
function loadMenuItems():void {
nbrOfMenuItems = xml.number_of_items;
//for (var i=0; i < nbrOfMenuItems; i++) {
//}
var i:int = 0;
for each (var m_item:XML in xml.menuitems.item) {
i++;
var menuItem:MenuItem = new MenuItem();
menuItem.x = 0;
menuItem.y = i * menuItem.height;
lblText = m_item.label;
menuItem.itemText.text = lblText;
menuItem.URL = m_item.url;
//We don’t want the text field to catch mouse events
menuItem.mouseChildren = false;
//Make the item look like a button (handcursor on hover)
menuItem.buttonMode = true;
//We want to listen when the mouse is over and out of the item
menuItem.addEventListener(MouseEvent.MOUSE_OVER, mouseOverItem);
menuItem.addEventListener(MouseEvent.MOUSE_OUT, mouseOutItem);
menuItem.addEventListener(MouseEvent.MOUSE_DOWN, mouseClick);
//Add the menuItem to the menuHolder
menuHolder.addChild(menuItem);
}
}
function addMenuItems():void{
//Create the MenuItems for the menu.
//Feel free to change the NUMBER_OF_ITEMS to what you want!
for (var i=0; i < NUMBER_OF_ITEMS; i++) {
//Create a new MenuItem
var menuItem:MenuItem = new MenuItem();
//Position the item.
//We will position the items from top to dowm.
menuItem.x = 0;
menuItem.y = i * menuItem.height;
//Set the text for the menuItem
menuItem.itemText.text = “Menu item ” + (i+1).toString();
//We don’t want the text field to catch mouse events
menuItem.mouseChildren = false;
//Make the item look like a button (handcursor on hover)
menuItem.buttonMode = true;
//We want to listen when the mouse is over and out of the item
menuItem.addEventListener(MouseEvent.MOUSE_OVER, mouseOverItem);
menuItem.addEventListener(MouseEvent.MOUSE_OUT, mouseOutItem);
//Add the menuItem to the menuHolder
menuHolder.addChild(menuItem);
}
}
function addListeners():void{
//Save the menuHolder’s height now that all the items have been added to it
HOLDER_HEIGHT = menuHolder.height;
//Add a listener when the mouse is over and out of the menuHolder
menuHolder.addEventListener(MouseEvent.MOUSE_OVER, mouseOverMenu);
menuHolder.addEventListener(MouseEvent.MOUSE_OUT, mouseOutMenu);
//Add ENTER_FRAME for the menu animation
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
//This function is called when the mouse is over the menu
function mouseOverMenu(e:Event):void {
mouseIsOver = true;
}
//This function is called when the mouse is out of the menu
function mouseOutMenu(e:Event):void {
mouseIsOver = false;
}
function mouseClick(e:Event):void{
var item:MenuItem = e.target as MenuItem;
var iURL = item.URL;
navigateToURL(new URLRequest(iURL), “_blank”);
trace(iURL);
}
//This function is called when the mouse is over an item
function mouseOverItem(e:Event):void {
//Save the item to a local variable
var item:MenuItem = e.target as MenuItem;
//Tween the item’s fill color.
TweenMax.to(item.itemFill, 0.01, {tint: 0xff8800});
}
//This function is called when mouse moves out of the item
function mouseOutItem(e:Event):void {
//Save the item to a local variable
var item:MenuItem = e.target as MenuItem;
//Tween the fill color to original state
TweenMax.to(item.itemFill, 0.5, {tint: 0×16222E});
}
//This function is called in each frame
function enterFrameHandler(e:Event):void {
//Check if the mouse is over the menu
if (mouseIsOver) {
//Calculate the vertical distance of how far the mouse is from
//the top of the mask.
var distance:Number = mouseY - myMask.y;
//Calculate the distance in percentages
var percentage:Number = distance / MASK_HEIGHT;
//Save the holder’s old y coordinate
oldY = menuHolder.y;
//Calculate a new y target coordinate for the menuHolder.
//We subtract the mask’s height from the menuHolder.
//Otherwise the menuHolder would move too far up when the mouse is at bottom.
//Remove the subraction to see for yourself!
var targetY:Number = -((HOLDER_HEIGHT - MASK_HEIGHT) * percentage) + myMask.y;
//Tween the menuHolder to the target coordinate
TweenMax.to(menuHolder, 0.4, {y: Math.round(targetY)});
}
}
Here is the struction of the XML file.
18
frameContent
Menu Label A
MenuURLa.asp
This has yet been implemented
Menu Label B
MenuURLb.asp
tooltip reserved for future enhancement
Bob B.,
Thanks for your addition, I’m having errors appear with your actionscript, can you give me the exact code example for the xml file, and is it possible to go to a frame label instead of a url when clicked, a working download zip file would be awesome if you have one I could use for reference, any help would be appreciated, thanks.
Please Please where is the xml file.. I have figure it out this awesome tutorial but I cant edit the XML file “coolmenu.xml” :(. Can anyone help? fla swf files works perfect but I cant see any menu item because of this help!!
The format of the XML file is as follows;
8
Went
went.html
A
a.html
Bit
Nuts.html
Nuts
Nuts.html
Getting
Getting.html
The
The.html
XML
XML.html
Format
Format.html
Copy the above text (between and ) into a new textfile called coolmenu.xml and save it into the same folder as your menu .fla file (ensure the file only has a .xml file extension on the end if you’re using Windows Notepad to create the file…)
Took me about 10 minutes of messing around with the flash code in debug to work out the XML, enjoy !
Regards,
Steve
arrrg!!!
Regarding my post above….this stupid site is stripping out the XML tags and just leaving the data, so Bob B’s post probably did contain the XML….
anyway, I’ll have another go with replaceing the with [ and ] (just replace them back when you create your XML file), here goes again;
[site]
[number_of_items]8[/number_of_items]
[menuitems]
[item]
[label]Went[/label]
[url]went.html[/url]
[/item]
[item]
[label]A[/label]
[url]a.html[/url]
[/item]
[item]
[label]Bit[/label]
[url]Nuts.html[/url]
[/item]
[item]
[label]Nuts[/label]
[url]Nuts.html[/url]
[/item]
[item]
[label]Getting[/label]
[url]Getting.html[/url]
[/item]
[item]
[label]The[/label]
[url]The.html[/url]
[/item]
[item]
[label]XML[/label]
[url]XML.html[/url]
[/item]
[item]
[label]Format[/label]
[url]Format.html[/url]
[/item]
[/menuitems]
[/site]
Thanks a lot for the tutorial. I was looking for something similar for a long time, found some components on flashcomponents.com but they are all for AS2.
Really appreciate it.
I have not succeeded. Help. Perhaps I am obtuse.
Error:
1172: Definition gs could not be found. import gs.*;
1172: Definition gs.plugins could not be found. import gs.plugins.*;
1172: Definition gs could not be found. import gs.*;
1172: Definition gs.plugins could not be found. import gs.plugins.*;
1120: Access of undefined property TweenMax.
TweenMax.to(item.itemFill, 0.01, {tint: 0xff8800});
1120: Access of undefined property TweenMax.
TweenMax.to(item.itemFill, 0.5, {tint: 0×16222E});
1120: Access of undefined property TweenMax.
TweenMax.to(menuHolder, 0.4, {y: Math.round(targetY)});
1120: Access of undefined property TweenPlugin. TweenPlugin.activate([AutoAlphaPlugin,TintPlugin]);
1120: Access of undefined property AutoAlphaPlugin.
TweenPlugin.activate([AutoAlphaPlugin,TintPlugin]);
1120: Access of undefined property TintPlugin. TweenPlugin.activate([AutoAlphaPlugin,TintPlugin]);
You have to save the folder “gs” from “greensock-tweening-platform-as3″ in the your project folder.
The “gs” folder contains Tween classes.
yeah the sony web site is nice i wonder how long that took even though most of the front page is directed to different sites within sony’s corporation.
Erhhh.. Their menu is nice, but it has nothing to do with this tutorial, you know
its good but i want the menu like http://www.sony.com
Can u help ? i want the mouse over menu and then stop dont run again and again plz check this site sony.com and give me tutorial about this menu plz
Thank you very much for the tutorial:) - great effort and result!
How different would the code be if you hadn’t used tweenMax?
Thank you very much, ty again:)
I will (or not) comment the code later, but, simply regarding the menu idea itself :
That’s awesome. Takes a moderate ammount of place and is able to store many links.
Bravo !
- Kemipso (Seriously, nice one)