This will be a general-purpose radial menu for use with Javascript, generated as SVG using the Snap.svg library (http://snapsvg.io/).
General Requirements
Simple example html page should be provided: menu will be initially hidden, first level "ring" will be shown on click, centered on click location
Selecting an item will optionally trigger a callback
If the selected item has "children" another level "ring" will be opened around the first
If a different inner item (parent) is selected, the outer rings will close and a new sub-level ring will open.
Additional 3rd party libraries should be avoided
Appearance
Color/stroke/fill/font and ring segment spacing will all be adjustable via configuration parameters
Size of segments is automatically calculated by default (each segment is 1/n of the ring, where n is the number of sibling menu items
Size can also be specified manually for a menu item as a float value 0..1, if the sum of all sibling sizes is >1, ignore them and calculate automatically.
When opening menu, ring will expand and fade in at click location. Similar to: http://codepen.io/suez/pen/vAais without rotation.
When opening-sub menu rings, they will also expand and fade in.
Text will always be "right-side up": items primarily on the lower-half of the menu will be flipped vertically so they are not upside-down.
Menu size (diameter) dynamically changes to allow all list items to be visible at specified font size
Configuration & Use
Two new Objects will be defined: RadialMenu, and RadialMenuItem
RadialMenu set configuration defaults, location, and contains multiple RadialMenuItem
RadialMenuItem can override configuration options as well as provide a callback for onClick
RadialMenuItem can have multiple children RadialMenuItem
Defaults for child items are inherited from the top-level RadialMenu not from the parent RadialMenuItem
Menu will be initialized via Javascript as follows, using optional configuration object. Default values are shown below.
//creating a new RadialMenu
var myMenu = new RadialMenu({
stroke: 1, //stroke width around every menu item, in pixels
spacing: 10 //amount of space between menu items
x: 0, //location of the center of the menu
y: 0,
opacity: 1.0
... //any child item configuration option can be specified here to set the default for the entire menu. the above options are only available on the RadialMenu
});
//calling .add() with optional configuration will add a new RadialMenuItem and return it
var myMenuItem = myMenu.add('menu-item-label',{
size: null, //if set to a float value 0-1, attempt to allow the section to take that percent of the circle. if null, size is automatically calculated by
font-size: 14, //font size of this item, in pixels
font-family: 'Verdana',
font-color: '#000000',
active-font-color: '#000000',
active-stroke-color: '#000000',
active-stroke-opacity: 1.0,
active-fill: '#ffffff',
active-fill-opacity: 1.0,
stroke-color: '#000000',
stroke-opacity: 1.0,
text-color: '#000000',
fill: '#ffffff',
fill-opacity: 0.5,
data: null, //optionally additional object can be provided that will be sent to the callback, this could include an ID or URL to load on click
onclick: null, //callback, none by default
});
configuration can be changed after creation using myMenu.x = 100 or myMenuItem['fill-opacity'] = 0.75 for example.
additonal functions:
myMenu.
myMenu.add(label,config); //add and return a top-level menu item
myMenu.children(); //return all child menu items as array
myMenu.close(); //will animate the entire menu to closed/hidden position
myMenuItem.close(); //if this menu item is open, it will animate to closed
myMenuItem.open(); //if this menu item is not open, it (and any parents if they are not open) will be marked as selected
myMenuItem.add(label,config); //add and return a child menu item
myMenuItem.children(); //return all child menu items as array
Example:
var myMenu = new RadialMenu({
opacity: 0.0,
fill-opacity: 1.0,
active-fill: '#cbcccb',
onclick: function(e){
//need to be able to reference source RadialMenuItem
//and optional .data attribute in here
//possibly through 'this.data' or 'e.target.data'
console.log('menu item clicked',this,e);
this.open();
}
});
var m1 = myMenu.add('RESIDENTIAL EXPERIENCE',{size:0.5});
var m2 = myMenu.add('HALL ARTS LEASING');
var m3 = myMenu.add('HALL GROUP');
m1.add('DESIGN TEAM');
m1.add('THE ARTS DISTRICT');
m1.add('AMENITIES');
m1.add('MORE');
m1.add('LIFESTYLE');
m2.add('HALL STRUCTURED FINANCE');
m2.add('ANGEL INVESTING');
m2.add('PHILANTHROPY');
m2.add('MORE');
m2.add('HALL OFFICE PARK');
/* ... add m3 children, other sub-sub children ...*/
var menuOpen = false;
$("body").on('click',function(e){
if(menuOpen) {
myMenu.opacity = 0;
}else {
myMenu.x = e.pageX;
myMenu.y = e.pageY;
myMenu.opacity = 1.0;
myMenu.open();
}
menuOpen = !menuOpen;
});
Radial Menu Library
This will be a general-purpose radial menu for use with Javascript, generated as SVG using the Snap.svg library (http://snapsvg.io/).
General Requirements
Appearance
1/n
of the ring, wheren
is the number of sibling menu itemstextPath
(http://snapsvg.io/docs/#Paper.text)Configuration & Use
RadialMenu
, andRadialMenuItem
RadialMenu
set configuration defaults, location, and contains multipleRadialMenuItem
RadialMenuItem
can override configuration options as well as provide a callback foronClick
RadialMenuItem
can have multiple childrenRadialMenuItem
RadialMenu
not from the parentRadialMenuItem
myMenu.x = 100
ormyMenuItem['fill-opacity'] = 0.75
for example.Example: