Cool 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


Filed under: ActionScript 3 Advanced
Tags:

Comments

14 Responses to “Cool Menu with ActionScript 3”
  1. Michael says:

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

    Reply
  2. Biyified says:

    great tut. Thanks

    Reply
  3. 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?

    Reply
  4. 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

    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

      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.

  5. _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.

    Reply
  6. 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]);

    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.

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

    Reply
  8. Kemipso says:

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

    Reply
  9. 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

    Reply
  10. 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:)

    Reply
  11. 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)

    Reply