PillMenu – Simple Pill Mootools Menu

8

Posted in Development | February 11, 2010

Motools LogoPillMenu is a simple Mootools class that helps you to add a nice effect to your menu.

DemoDownload

THE HTML

How you can see, this is a typical list with a div container used to apply the script and render the style. I added pillMenu class to give it a default style, but you can replace it with another class like nav or nav-wrap of wordpress.

Selected is the name of the class for the selected menu, this class name can be changed in the options of Mootools class. Change in “current_page_item” if you want to use the script with the list of  pages in wp.

<div id="menu1" class="pillMenu">
	<ul>
		<li class="selected"><a href="#" title="Go to Home Page">Home</a></li>
		<li><a href="#" title="Go to About Page">About</a></li>
		<li><a href="#" title="Go to Archive Page">Archive</a></li>
		<li><a href="#" title="Go to Sitemap Page">Sitemap</a></li>
		<li><a href="#" title="Go to Contact Page">Contact</a></li>
		<li><a href="#" title="Go to Long Text Menu Page">Long Text Menu</a></li>
	</ul>
	<div class="clearfix"></div>
</div>

THE CSS

These are the style rows of code that you have to add in your css file if you want an horizontal movement, I added also clearfix style, but if you have your own you can remove it.

The class .pill is the class of pill that you can customize, actually it is only a transparent block with 1px border, but, if you want, you can replace it with a background or a single line.

If you decide to change the name of the selected class, remember to change it also in the css.

.pillMenu{ position: relative; }
.pillMenu ul{ margin: 0; padding: 0; position: relative; }
.pillMenu ul li{ float: left; list-style: none; margin: 0 5px; position: relative; z-index: 10; }
.pillMenu ul li a{ color: #000; display: block; padding: 5px 10px; text-decoration: none; }
.pillMenu ul li.selected{ background-color: #000; border: 1px solid #000; }
.pillMenu ul li.selected a{ color: #fff; }
.pillMenu .pill{ border: 1px solid #666; }
.pillMenu .clearfix{ clear:both; display:block; height:0; font-size:0; line-height:0 }

This is the version of css for a vertical movement.

.pillMenu_vertical{ position: relative; width: 75px; }
.pillMenu_vertical ul{ margin: 0; padding: 0; position: relative; }
.pillMenu_vertical ul li{ list-style: none; margin: 5px; position: relative; z-index: 10; }
.pillMenu_vertical ul li a{ color: #000; display: block; padding: 5px 10px; text-decoration: none; }
.pillMenu_vertical ul li.selected{ background-color: #000; border: 1px solid #000; }
.pillMenu_vertical ul li.selected a{ color: #fff; }
.pillMenu_vertical .pill{ border: 1px solid #666; }

The MooTools Class

var PillMenu = new Class({

	//implements
	Implements: [Options,Events],

	//options
	options: {
		vertical: 0,
		pillClass: 'pill',
		selectedClass: 'selected',
		duration: 'short',
		transition: Fx.Transitions.Linear
	},

	//initialization
	initialize: function(element,options) {
		//set options
		this.setOptions(options);
		//set element
		this.element = document.id(element);
		//set pill element
		this.pill = this.element.getElement('.pill');

		if(!this.pill){
		    //build pill element
		    this.pill = new Element('div',{
		    	'class': this.options.pillClass,
		    	'style': 'position:absolute; z-index:1;'
		    });
		    //inject pill into element
		    this.pill.inject(this.element,'top');
		}
		//make effect
		this.pillFx = new Fx.Morph(this.pill, {'duration': this.options.duration, 'link': 'cancel', 'transition': this.options.transition});

		this.start();
	},

	start: function() {
		//fire event start
		this.fireEvent('start');

        this.element.getElements('li').each(function(el,i){
			//detect selected menu
			if(el.hasClass(this.options.selectedClass)){
				//save selected menu
				this.selected = el;
				//set pill dimensions
				this.pill.setStyles({
				    width: el.getStyle('width'),
				    height: el.getStyle('height'),
				    left: el.getPosition().x - this.element.getPosition().x,
				    top: el.getPosition().y - this.element.getPosition().y
				});

			}						

			//add event to element
			el.addEvent('mouseenter', function(){
				//fire event start
				this.fireEvent('change');
				//set effect for horizontal and vertical style
				if(!this.options.vertical){
					this.pillFx.start({
					    'left': [this.pill.getStyle('left'), el.getPosition().x - this.element.getPosition().x],
					    'width': [this.pill.getStyle('width'), el.getStyle('width')]
					});
				} else {
					this.pillFx.start({
					    'top': [this.pill.getStyle('top'), el.getPosition().y - this.element.getPosition().y],
					    'height': [this.pill.getStyle('height'), el.getStyle('height')]
					});
				}

			}.bind(this));

		}.bind(this));

        //add event to reset all
        this.element.addEvent('mouseleave', function(){
        	//set effect for horizontal and vertical style
        	if(!this.options.vertical){
        		this.pillFx.start({
				    'left': [this.pill.getStyle('left'), this.selected.getPosition().x - this.element.getPosition().x],
				    'width': [this.pill.getStyle('width'), this.selected.getStyle('width')]
				});
			} else {
				this.pillFx.start({
				    'top': [this.pill.getStyle('top'), this.selected.getPosition().y - this.element.getPosition().y],
				    'height': [this.pill.getStyle('height'), this.selected.getStyle('height')]
				});
			}			

		}.bind(this));

	}

});

The following are arguments, options, and events for PillMenu:

Arguments

  • element: The element to apply the script
  • option: The class options

Options

  • vertical: [0/1] makes the movement horizontal or vertical
  • pillClass: [pill] name of class to give to pill element
  • selectedClass: [selected] name of class of selected menu item
  • duration: [short] time of duration of transition
  • transition: [Fx.Transitions.Linear] transition to apply

Events

  • start: Fire when the script is started
  • change: Fire when the mouse go over the menu item

Usage

These are a lot of examples that you can add to your domready to use the script.

window.addEvent('domready',function() {
	//example for default menu
	var myMenu1 = new PillMenu('menu1');

	//example for vertical menu
	var myMenu1 = new PillMenu('menu1', {vertical: 1});

	//example for elastic menu
	var myMenu1 = new PillMenu('menu1', {
		duration: 'long',
		transition: Fx.Transitions.Elastic.easeOut
	});

	//example for event actions
	var myMenu4 = new PillMenu('menu4', {
  		onStart: function() {
			alert('Start');
		},
  		onChange: function() {
			alert('Change');
		}
	})
});

This script is released under the MIT and GPL licenses, feel free to edit and use it everywhere.

DemoDownload