Menu with ActionScript 3

February 17, 2009 by: smonte

This 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!).

Dynamic text field inside the movie clip

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“.

Movie Clip Item Fill Color

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.

Mask for Flash Menu

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.

  • Digg
  • Sphinn
  • del.icio.us
  • Mixx

Related tutorials:

  1. Vertical Menu with Actionscript 3 and XML
  2. Colorful Menu with XML and ActionScript 3
  3. Image Fill with ActionScript 3
  4. Vertical 3D Carousel with ActionScript 3
  5. Vertical 3D Carousel with ActionScript 3 and XML



Filed under: ActionScript 3 Advanced
Tags:

Comments

23 Responses to “Menu with ActionScript 3”
  1. rafighi says:

    every thing is ok and easy but i can’t understand how i can use and related the class to my menu so i have many errors about “import gs.*” and “Andimport gs.plugins.*”

    please help me fix the errors

    Log in to Reply
  2. 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.

    Log in to Reply
  3. Travis says:

    really great!..

    Log in to Reply
  4. MDQ says:

    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

    Log in to Reply
  5. Annditta says:

    this is nice

    Log in to Reply
  6. Adrian says:

    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

    Log in to Reply
  7. Michael says:

    How can I add functionality for these buttons??
    Sorry for noob question but i am beginner:)
    Please help

    Log in to Reply
  8. Biyified says:

    great tut. Thanks

    Log in to Reply
  9. Paul says:

    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?

    Log in to Reply
  10. jonathan says:

    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

    Log in to Reply
    • Bob B. says:

      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

      Log in to Reply
      • Kevin K says:

        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.

      • semih says:

        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!!

      • sroberts says:

        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

      • sroberts says:

        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]

  11. _MD_ says:

    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.

    Log in to Reply
  12. Serg says:

    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]);

    Log in to Reply
    • Elena says:

      You have to save the folder “gs” from “greensock-tweening-platform-as3″ in the your project folder.
      The “gs” folder contains Tween classes.

      Log in to Reply
  13. jackass says:

    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.

    Log in to Reply
  14. Kemipso says:

    Erhhh.. Their menu is nice, but it has nothing to do with this tutorial, you know :-|

    Log in to Reply
  15. Pinky says:

    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

    Log in to Reply
  16. Trinity says:

    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:)

    Log in to Reply
  17. Kemipso says:

    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)

    Log in to Reply

Leave a Reply

You must be logged in to post a comment.