
Download: AS2 Group94 Circular Menu
I built this circular version of the group94 style scrolling menu for a flash website awards showcase I was asked to work on. The original design was based around circles, but we ended up redesigning as parts of the interface (not this menu!) were too processor intensive.
Ok, so part two of my tribute to Group 94’s menu system! This is again inspired by the Group 94 (at least they are most famous for it) shuffle menu in Flash, which pushes items off the top and bottom as the menu shuffles into place.
This version is circular though, and each menu item rotates around a pivot. Initiating the prototype with particular variables will define the spacing between items, the radius of the Group 94 circular menu and the amount of items visible at one time.
Please note, this is in no way a rip of the Group 94 menu. In fact, I haven’t even seen a circular version which is why I made it. I have no idea how Group 94’s actionscript looks, or how they would have approached this style of menu. I do know however, that they have produced many innovative navigation systems, and so this is a simple tribute to their talent and innovation.
As with the regular group 94 scrolling menu, you will need Fuse installed, though all it does is handle tweening so you could use tweener or the inbuilt Flash tweening functions. I just prefer Fuse!
How it is done.
First import Fuse for tweening, then setup the array we will use for the menu:
import com.mosesSupposes.fuse.*;
ZigoEngine.simpleSetup (Shortcuts,PennerEasing);
var planets:Array = new Array ();
planets.push ("Mercury");
planets.push ("Venus");
planets.push ("Earth");
planets.push ("Mars");
planets.push ("Jupiter");
planets.push ("Saturn");
planets.push ("Uranus");
planets.push ("Neptune");
planets.push ("Pluto");
Then some very basic functionality for each menu button. I have ommited rollOvers for the demo…
MovieClip.prototype.circNavBtn = function (id:Number, par:MovieClip, name:String)
{
this.pos = this.id = id;
this.par = par;
this.btn.txt.text = name.toUpperCase ();
this._rotation = 90;
this._alpha = 0;
this.onPress = function ()
{
this.par.circNavRot (this.pos);
this.activeBtn ();
};
};
Then two small prototypes to handle the activation and de-activation of the buttons when the scroll function is called:
MovieClip.prototype.activeBtn = function ()
{
activeNavBtn.inactiveBtn ();
activeNavBtn = this;
this.btn.scaleTo (200,0.5);
this.enabled = false;
};
MovieClip.prototype.inactiveBtn = function ()
{
this.btn.scaleTo (100,0.5);
};
Then the main shuffle or rotation function, which designates tweens to all visible movieClips and hides those outside of the visible items range.
MovieClip.prototype.circNavRot = function (num:Number)
{
var diff:Number = num;
for (var i:Number = 0; i < this.btns.length; i++)
{
var btn:MovieClip = this["navBtn" + i];
btn.pos -= diff;
if (Math.abs (btn.pos) < this.visItems)
{
var offset:Number;
btn.pos != 0 ? (offset = btn.pos > 0 ? 15 : -15) : offset = 0;
var rot:Number = offset + (this.spacing * btn.pos);
var alph:Number = 100 - ((100 / this.visItems) * Math.abs (btn.pos));
var scl:Number = 100 - (5 * Math.abs (btn.pos));
btn.rotateTo (rot,0.5,"easeOutExpo");
btn.alphaTo (alph,0.5);
btn.btn.scaleTo (scl,0.5);
}
else
{
btn.stopTween ("_alpha");
btn.stopTween ("_rotation");
btn._rotation = btn.pos > 0 ? 90 : -90;
btn._alpha = 0;
}
btn.enabled = Math.abs (btn.pos) < this.visItems;
}
this["navBtn" + num].activeBtn ();
};
Now we setup the circular scrolling menu on a movieClip:
MovieClip.prototype.circNav = function (array:Array, radius:Number, spacing:Number, visItems:Number)
{
this.btns = new Array ();
this.spacing = spacing;
this.visItems = visItems;
for (var i:Number = 0; i < array.length; i++)
{
var navBtn:MovieClip = this.createEmptyMovieClip ("navBtn" + i, i);
var btnTxt:MovieClip = navBtn.attachMovie ("btn", "btn", 0);
btnTxt._x = radius;
navBtn.circNavBtn (i,this,array[i]);
this.btns.push (navBtn);
}
this.circNavRot (0);
};
Here we dynamically create a movieClip, position it, then call our prototype to create the lovely Group94 style menu…
var testMenu:MovieClip = this.createEmptyMovieClip ("nav", 0);
testMenu._x = 20;
testMenu._y = 112;
testMenu.circNav (planets, 60, 15, 4);
And finally we add the ability to use the mouse wheel to scroll the menu. otherwise we just click the menu items:
var mouseListener:Object = new Object ();
mouseListener.onMouseWheel = function (delta)
{
var navIndex:Number = activeNavBtn.id;
if (delta < 0 && activeNavBtn.id < planets.length - 1)
{
testMenu.circNavRot (1);
testMenu["navBtn" + (navIndex + 1)].activeBtn ();
}
else if (delta > 0 && activeNavBtn.id > 0)
{
testMenu.circNavRot (-1);
testMenu["navBtn" + (navIndex - 1)].activeBtn ();
}
};
Mouse.addListener (mouseListener);
I hope this is useful to someone! If you find a home for it, please let me know.
Download: AS2 Group94 Circular Menu
Hello, very very .. cool menu, i want to ask you something :
How can i make the same menu but in the other side rotation?
I need to have a menu with the half circle on the left side.
With hope, thanks for now.
bye nunzio
Hello, great script.
I want to know can i make the button’s works, like gotoAndStop(someframe);
Thanks in advance.
Hey Leo,
You can use the activeBtn and inactiveBtn prototypes. For example:
MovieClip.prototype.activeBtn = function () { activeNavBtn.inactiveBtn (); activeNavBtn = this; this.btn.scaleTo (200,0.5); // Extra script this.gotoAndStop( 'activeFrame'); // End extra script this.enabled = false; }; MovieClip.prototype.inactiveBtn = function () { this.btn.scaleTo (100,0.5); // Extra script this.gotoAndStop( 'inActiveFrame'); // End extra script };Hello,
I love your work, and I would really want to have a version of this circular menu in Actionscript 3.
I have been trying to dissect the code and re-constitute something that would look like Actionscript3, but its quite tough for my level of knowledge.
If you have an AS3 version of this menu bar, I would be very thankful ;)
Aurel
Hi Aurelplouf
AS3 version is now available!
It’s not a direct conversion, but rather a new version with a ton of cool new features. Hope you like it…
http://blog.soulwire.co.uk/flash/actionscript-3/as3-g94-circular-menu/
Hi
Great job!!!
Someone can help me ? if possible change you array into a Xml file
Thanks guys
nobody can help?
Hi Big Jo.
why don’t you try this:
Make an XML file:
Then parse the XML file and create the circular menu using the XML nodes:
var planetsList:Array = []; planetsXML = new XML (); planetsXML.ignoreWhite = true; planetsXML.onLoad = function (success) { if (success) { var path:XML = this.firstChild; var nodes:Number = path.childNodes.length; for (var i:Number = 0; i < nodes; i++) { planetsList.push (path.childNodes[i].firstChild); } var testMenu:MovieClip = this.createEmptyMovieClip ("nav", 0); testMenu._x = 20; testMenu._y = 112; testMenu.circNav (planets,60,15,4); } }; planetsXML.load ('planets.xml');That should do it :)
Hi Soulwire Thanks for you answer but steel dont working i dont no why ?
Try copying the block of code that parses the XML and the call to load it (“planetsXML.load(‘planets.xml’);“) and pasting it at the bottom of your code, after the code for the prototypes. That should solve it because it will register the prototypes before you attempt to use them (in the line “testMenu.circNav (planets,60,15,4);” )
I have tried but nothing happend , i trace the xml “trace(planetsList);” that ok! flash call the xml but the node dont attach ” testMenu”
Thanks Soulwire for your help
Haha, sorry! I’ve just realised I wasnt paying attention to something. It’s been a while since I wrote AS2 and I didn’t look closely at what I wrote. Saying var testMenu:MovieClip = this.createEmptyMovieClip(“nav”, 0); within the scope of the XML onload function means that “this” is referring to the XML and not the root. So try instead:
var planetsList:Array = []; var testMenu:MovieClip = this.createEmptyMovieClip ("nav", 0); testMenu._x = 20; testMenu._y = 112; planetsXML = new XML (); planetsXML.ignoreWhite = true; planetsXML.onLoad = function (success) { if (success) { var path:XML = this.firstChild; var nodes:Number = path.childNodes.length; for (var i:Number = 0; i < nodes; i++) { planetsList.push (path.childNodes[i].firstChild.toString()); } testMenu.circNav (planetsList,60,15,4); } }; planetsXML.load ('planets.xml');