YUI 3 Radial Menu Gallery Component


The RadialMenu gallery component is finished and available on GitHub at http://github.com/mattsnider/yui3-gallery/downloads. The latest version of the RadialMenu improves on the previous two articles by having the RadialMenu and RadailMenuPanel objects extend Overlay. By using the overlay component, RadialMenu can leverage the knowledge and experience that went into developing overlay, and we remove the need to mask the page with an invisible div.

Getting ready

You will need to include the following for the RadialMenu component to work:

<link type="text/css" href="http://github.com/mattsnider/yui3-gallery/raw/master/build/gallery-radialmenu/assets/radialMenu.css" rel="stylesheet"/>

<script type="text/javascript" src="http://yui.yahooapis.com/3.0.0/build/yui/yui.js"></script>
<script type="text/javascript">YUI({
	modules: {
		'gallery-radialmenu': {
			fullpath:'http://github.com/mattsnider/yui3-gallery/raw/master/build/gallery-radialmenu/gallery-radialmenu-min.js',
			requires: ['overlay', 'collection', 'event-mouseenter', 'node'],
			optional: ['plugin', 'anim'],
			supersedes: []
		}
	}
}).use('gallery-radialmenu', function(Y) {
	// use the Gallery Radial Menu here
});
</script>

How to do it…

Create a simple RadialMenu with 4 panels:

YUI(...).use('gallery-radialmenu', function(Y) {
	var radialMenu = new Y.RadialMenu({panels: [
		new Y.RadialMenuPanel({content: '0'}),
		new Y.RadialMenuPanel({content: '1'}),
		new Y.RadialMenuPanel({content: '2'}),
		new Y.RadialMenuPanel({content: '3'})
	]});
	radialMenu.render();
	radialMenu.show();
});

Create a more complex RadialMenu, changing all the default values:

YUI(...).use('gallery-radialmenu', function(Y) {
	var conf = {
		centerPoint: [100, 100],
		closeOnClick: false,
		diameter: 200,
		keyHoldTimeout: 1000,
		panels: [
			new Y.RadialMenuPanel({content: '0'}),
			new Y.RadialMenuPanel({content: '1'}),
			new Y.RadialMenuPanel({content: '2'}),
			new Y.RadialMenuPanel({content: '3'}),
			new Y.RadialMenuPanel({content: '4'}),
			new Y.RadialMenuPanel({content: '5'})
		],
		useMask: true
	};
	var radialMenu = new Y.RadialMenu(conf);
	radialMenu.render();
	radialMenu.show();
});

Create a RadialMenu, where you specify the bounding box for the menu and panels:

YUI(...).use('gallery-radialmenu', function(Y) {
	var radialMenu = new Y.RadialMenu({boundingBox: '#radialMenu', panels: [
		new Y.RadialMenuPanel({boundingBox: '#radialMenuPanel0'}),
		new Y.RadialMenuPanel({boundingBox: '#radialMenuPanel1'}),
		new Y.RadialMenuPanel({boundingBox: '#radialMenuPanel2'}),
		new Y.RadialMenuPanel({boundingBox: '#radialMenuPanel3'})
	]});
	radialMenu.render();
	radialMenu.show();
});

Create a RadialMenu that animates open and closed:

YUI(...).use('gallery-radialmenu', function(Y) {
	var radialMenu = new Y.RadialMenu({panels: [
		new Y.RadialMenuPanel({content: '0'}),
		new Y.RadialMenuPanel({content: '1'}),
		new Y.RadialMenuPanel({content: '2'}),
		new Y.RadialMenuPanel({content: '3'})
	]});
	var animConf = {
		animType: 'rotate',
		duration: 2, // seconds
		easingIn: Y.Easing.easeIn,
		easingOut: Y.Easing.easeOut,
		rotation: 180
	};
	radialMenu.plug(Y.RadialMenuAnim, animConf);
	radialMenu.render();
	radialMenu.show();
});

Listen for RadialMenu events:

YUI(...).use('gallery-radialmenu', function(Y) {
	// define your RadialMenu
	// ...
	radialMenu.on('panelClicked', function(e) {
		// this will fire anytime a panel is clicked
	});
	radialMenu.on('panelClicked1', function(e) {
		// this will fire anytime the panel at index 1 is clicked
	});
});

How it works…

The RadialMenu and RadialMenuPanel objects each extend the Overlay component, so they inherit all the configuration properties from Overlay. By default the DOM behind the RadialMenu overlay remains hidden, unless you set the useMask property to true. This will cause the page to be masked by the RadialMenu DOM, so that end-users can only interact with the menu. When the RadialMenu is shown the RadialMenuPanels appear evenly spaced on a circle with the provided diameter (or 100 pixels by default) around the centerPoint (or center of the viewport by default). You can also specify whether the RadialMenu should close whenever a click event occurs in the DOM by setting closeOnClick to true (this is true by default). And you can change the delay used to move between panels while holding down an arrow key by adjusting number of milliseconds for the keyHoldTimeout value (this is 500ms by default).

For the RadialMenuPanels you can programatically set the content by defining the content property of the configuration object. This must be a string, but can contain HTML as the innerHTML property is used to apply this value. The boundingBox or contentBox can be manually specified to point to an existing DOM element. You can change the hoverClass used by the RadialMenuPanel, but for most cases, the default radialMenuPanel-hover value should suffice. The remaining properties of the RadialMenuPanel (centerpt, index, and radialpt) are used internally to handle drawing and animating the panels.

The RadialMenuAnim is an optional functionality that will be included if you set loadOptional to true when calling YUI(). There are currently two types of animations that can be specified as the animType property: rotate and radiate. The rotation animation will move the panels around the circle as they expand into the proper final position, while the radiate animation will push the panels out linearly from the center to their final position. The animation duration can be changed by modifying the value of the duration property (the default is 1 second). The animation used for the opening and closing animation can be modified by changing the easingOut and easingIn properties respectively; this value should be set to an easing function. Lastly, if using the rotate animation then the number of degrees to rotate can be specified on the rotation property.

Besides all the events that come standard with YUI 3 widgets, the RadialMenu has two additional events: panelClicked and panelClicked#. The callbacks for both events will be passed the target of the click event as their first argument and the RadialMenuPanel object as their second. The panelClicked event fires anytime any panel is clicked and the panelClicked# event fires anytime a panel at the specified index is clicked.

See also

The http://www.mattsnider.com/widget/radial-menu/ article, which introduces the RadialMenu concept.

The http://www.mattsnider.com/widget/radial-menu-key-events/ article, which show how keyboard events are attached to the radial menu.

The test page, Radial Menu Test, where you can play with the animations yourself.