I'm fairly new to JS/jQuery (a few months), and I think it's time to start getting involved in the community. So I wrote a little plugin. Nothing revolutionary. Really, the project is to write a clean, workable plugin. Any and all thoughts and suggestions on how I can make the code cleaner, or the animations smoother, or anything, are very much appreciated.
Here's the plugin in action: http://jsfiddle.net/VA7P5/
Here is the plugin code:
(function ($) {
$.fn.menuBar = function (options) {
var defaults = {
width: 145, // Width of Sidebar
left: true, // If true, sidebar is positioned left. If false, it's positioned right
height: 80, // Height of footer
barColor: '#000', // Color of three-bar menu before it's opened
menuBackground: '#303030', // Background color of sidebar and footer
closeColor: '#fff' // Color of close-button
};
var options = $.extend(defaults, options);
return this.each(function () {
var i = $(this);
var o = options;
var width = $('nav.sidebar').css('width');
var height = $('footer.hidden').css('height');
var closeColor = $('.bar').css('background');
var barColor = $('.bar').css('background');
var barOne = $('.menu-bar-top');
var barTwo = $('.menu-bar-bottom');
var barThree = $('.menu-bar-mid');
var menuTrigger = $('nav.sidebar a');
var fadeWrapper = $('#fade-wrapper');
var nav = $('nav.sidebar');
var footerHidden = $('footer.hidden');
var bar = $('.bar');
bar.css('background', o.barColor);
if (o.left) {
nav.css({
'width': o.width,
'left': o.width - (o.width * 2),
'background': o.menuBackground
});
$('.menu-trigger').css({
'left': 0
});
} else {
nav.css({
'width': o.width,
'right': o.width - (o.width * 2),
'background': o.menuBackground
});
$('.menu-trigger').css({
'right': 0
});
}
footerHidden.css({
'height': o.height,
'bottom': o.height - (o.height * 2),
'background': o.menuBackground
});
i.click(function(){
if (i.hasClass('open')) {
closeMenu();
i.removeClass('open');
// Allow scrolling again when menu is closed
$('body').css('overflow', '');
} else {
openMenu();
i.addClass('open');
// No scrolling while menu is open
$('body').css('overflow', 'hidden');
}
});
$('#fade-wrapper').click(function(){
closeMenu();
i.removeClass('open');
$('body').css('overflow', '');
});
/*===========================================================================================================
Opening/Closing Functions
===========================================================================================================*/
function openMenu() {
fadeWrapper.fadeIn(100, function(){
barOne.css({
'top': '8px',
'transform': 'rotate(405deg)',
'-webkit-transform': 'rotate(405deg)',
'-moz-transform': 'rotate(405deg)',
'-ms-transform': 'rotate(405deg)',
'-o-transform': 'rotate(405deg)'
});
barTwo.css({
'top': '8px',
'transform': 'rotate(-405deg)',
'-webkit-transform': 'rotate(-405deg)',
'-moz-transform': 'rotate(-405deg)',
'-ms-transform': 'rotate(-405deg)',
'-o-transform': 'rotate(-405deg)'
});
if (o.left) {
nav.animate({'left': '+=' + o.width}, 200);
} else {
nav.animate({'right': '+=' + o.width}, 200);
}
footerHidden.animate({'bottom': '+=' + o.height}, 200);
barThree.fadeOut(100);
bar.css('background', o.closeColor);
});
}
function closeMenu() {
setTimeout(function(){
barThree.fadeTo(100, 1);
fadeWrapper.fadeOut(100);
if (o.left) {
nav.animate({'left': '-=' + o.width}, 200);
} else {
nav.animate({'right': '-=' + o.width}, 200);
}
footerHidden.animate({'bottom': '-=' + o.height}, 200);
bar.css('background', o.barColor);
barOne.css({
'top': '3px',
'transform': 'rotate(360deg)',
'-webkit-transform': 'rotate(360deg)',
'-moz-transform': 'rotate(360deg)',
'ms-transform': 'rotate(360deg)',
'o-transform': 'rotate(360deg)'
});
barTwo.css({
'top': '13px',
'transform': 'rotate(-360deg)',
'-webkit-transform': 'rotate(-360deg)',
'-moz-transform': 'rotate(-360deg)',
'-ms-transform': 'rotate(-360deg)',
'-o-transform': 'rotate(-360deg)'
});}, 1);
}
});
};
})(jQuery);
The necessary HTML:
<nav class="sidebar">
<a class="menu cursor" title="Menu">
<div class="menu-trigger">
<div class="bar-container">
<div class="bar menu-bar-top"></div>
<div class="bar menu-bar-mid"></div>
<div class="bar menu-bar-bottom"></div>
</div>
</div>
</a>
<!-- Sidebar content goes here -->
</nav>
<div id="fade-wrapper"></div>
<footer class="hidden">
<!-- Footer content goes here -->
</footer>
The necessary CSS:
a.cursor {
cursor: pointer;
}
#fade-wrapper {
display: none;
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.3);
z-index: 5000;
}
nav.sidebar {
position: fixed;
top: 0;
height: 100%;
z-index: 9999;
}
.menu-trigger {
position: fixed;
top: 8px;
width: 40px;
height: 20px;
line-height: 40px;
}
.bar-container {
margin-top: 3px;
height: 13px;
}
.bar {
position: absolute;
height: 3px;
width: 90%;
outline: 1px solid transparent;
-webkit-transition: all .5s ease;
-moz-transition: all .5s ease;
-ms-transition: all .5s ease;
-o-transition: all .5s ease;
transition: all .5s ease;
}
.menu-bar-top {
top: 3px;
left: 2px;
}
.menu-bar-mid {
top: 8px;
left: 2px;
}
.menu-bar-bottom {
top: 13px;
left: 2px;
}
footer.hidden {
position: fixed;
left: 0;
width: 100%;
z-index: 9999;
}