Skip to main content
3 of 5
deleted 4 characters in body
Justin
  • 175
  • 8

Menu Bar Animation Plugin

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;
}
Justin
  • 175
  • 8