Анимированное меню с помощью jQuery

Создадим анимированное меню для сайта ресторана. Сделаем пункты меню анимированными, и при клике на один из них будет выплывать окошко с информацией. А фоновое изображение будет менять цвет, в зависимости от открытого меню. Меню ресторана будет отображено в категориях. В блоке будет находится информация про напитки или блюда. После появления блока, меню будет скрываться. При закрытии контента, меню снова будет отображаться.

Структура

В HTML используем  несколько элементов для фонового изображения, главное меню, иконки загрузки, сетки.



<div id="ac_background" class="ac_background">
<img class="ac_bgimage" src="images/Default.jpg" alt="Фон"/>
<div class="ac_overlay"></div>
<div class="ac_loading"></div>
</div>

После того как загрузится страница, по умолчанию отобразится изображение Default.jpg. При клике по любому пункту меню, используемое фоновое изображение будет переходить в другое.
Меню будет заключено в блок div с классом “ac_content”. Тут поместим заголовок и список без нумерации для пунктов меню, спрятанный в div с классом “ac_menu”.


<div id="ac_content" class="ac_content">
<h1><span>Cafe + Bar</span>Dhalia</h1>
<div class="ac_menu">
<ul>
<li>
<a href="images/Appetizers.jpg">Appetizers</a>
<div class="ac_subitem">
<span class="ac_close"></span>
<h2>Appetizers</h2>
<ul>
<li>
A wonderful serenity has taken possession
of my entire soul, like these sweet mornings
of spring which I enjoy with my whole heart.
</li>
<li>Lobster Bisque</li>
<li>Smoked Salmon Terrine</li>
<li>Tuna Ceviche</li>
<li>Wild Mushroom Flan</li>
<li>Almond Bruschetta</li>
<li>Green Chilli Canapee</li>
<li>Artichoke Rucula Salad</li>
</ul>
</div><!-- ac_subitem-->
</li>
...
</ul>
</div><!-- ac_menu -->
</div><!-- ac_content -->


Каждому пункту меню создается блок div с классом “ac_subitem” с необходимой информацией. Сюда также можно помещать другой список или любой другой контент.
Ссылки главного меню будут направлять к изображениям, которые будут отображаться при нажатии на нужный пункт меню.
Перейдем к стилям
CSS
Самым первым подключим файл reset.css:


@import url('reset.css');


Фон элемента body сделаем черным, тогда при изменении изображения, фон будет темнеть.


body{
    background:#000;
    color:#fff;
    font-family: 'PT Sans Narrow', Arial, sans-serif;
    text-transform:uppercase;
}


Сделаем цвет под ссылками белым цветом:


a{
    color:#fff;
    text-decoration:none;
}


Фоновые изображения назначаются через JavaScript. Расположения и размеры изображений будут динамическими и будут зависеть от величины мониторов пользователей.


img.ac_bgimage{
    position:fixed;
    left:0px;
    top:0px;
    opacity:0.8;
    display:none;
}


Над изображением отобразим специальный паттерн.


.ac_overlay{
    width:100%;
    height:100%;
    position:fixed;
    top:0px;
    left:0px;
    background:transparent url(../images/pattern.png) repeat top left;
}


Иконку загрузки помещаем в верхний правый угол. Ее увидим при смене изображения.


.ac_loading{
    position:fixed;
    top:10px;
    right:10px;
    background:#000 url(../images/loader.gif) no-repeat center center;
    width:50px;
    height:50px;
    border-radius:10px 10px 10px 10px;
    z-index:999;
    opacity:0.7;
    display:none;
}


Блок с контентом расположен по центру. Для этого нужно атрибуту top присвоить значение 50% и уменьшить его высоту, сделав 50%.


.ac_content{
    position:fixed;
    height:90px;
    width:100%;
    top:50%;
    left:0px;
    margin-top:-65px;
}


Фон внизу заголовка делаем полупрозрачным черным. Стили h1 и span определяем отдельно. Справа добавляем рамку в 1 пиксель.


.ac_content h1{
    background:transparent url(../images/bg_menu.png) repeat top left;
    display:block;
    float:left;
    width:90px;
    height:50px;
    padding:20px;
    font-size:36px;
    font-weight:bold;
    line-height:20px;
    margin-right:1px;
}
.ac_content h1 span{
    display:block;
    font-weight:normal;
    font-size:14px;
}


Меню будет иметь такой же фон блока, с начальной шириной 0 пикселей. С помощью JavaScript, при загрузке страницы, увеличим ее до длины окна.


.ac_menu{
    background:transparent url(../images/bg_menu.png) repeat top left;
    float:left;
    position:relative;
    height:90px;
    width:0px;
}


Определям стиль для списка без нумерации:


.ac_menu > ul{
    float:right;


Для высоты элементов зададим атрибут overflow: hidden. Если их упустить, ссылки будут видны во время анимации:


.ac_menu > ul > li{
    float:left;
    position:relative;
    height:90px;
    overflow:hidden;
}


Ссылки скрыты с помощью атрибутов margin-top и opacity. Мы их перемещаем на середину (margin-top: 0px) и делаем их видимыми, задав значению opacity увеличение. Ссылки будут немного задерживаться, это придает виду интересный эффект.


.ac_menu > ul > li a{
    margin-top:60px;
    opacity:0;
    display:block;
    height:90px;
    padding:0px 10px;
    text-align:center;
    line-height:90px;
    outline:none;
    font-size:18px;
    font-weight:bold;
    text-shadow:1px 1px 1px #000;
}


Изначально блоки с иформацией имеют ширину 400 пикселей и высоту 0 пикселей. Плавно увеличиваем это значение  и margin-top, чтобы из середины выплывало окошко.


.ac_subitem{
    width:400px;
    height:0px; /* animate to 400px */
    top:50%;
    right:0px;
    margin-top:0px; /* animate to -200px */
    position:fixed;
    z-index:99;
    overflow:hidden;
    background:transparent url(../images/bg_menu.png) repeat top left;
}


Для блока с контентом определим некоторые стили:


.ac_subitem h2{
    font-size:22px;
    font-weight:bold;
    color:#fff;
    padding: 40px 0px 0px 40px;
    text-shadow:0px 0px 1px #000;
}
.ac_subitem ul{
    padding:0px 40px;
}
.ac_subitem ul li{
    margin:10px 0px;
}
.ac_subitem ul li:first-child{
    font-size:14px;
    text-transform:none;
    border-bottom:1px dotted #333;
    padding-bottom:15px;
    margin-bottom:15px;
}


В верхний правый угол блока добавим иконку:


span.ac_close{
    float:right;
    margin:10px;
    width:11px;
    height:12px;
    cursor:pointer;
    background:transparent url(../images/close.png) no-repeat top left;
    opacity:0.4;
}
span.ac_close:hover{
    opacity:1.0;
}


Переходим к анимации.
JavaScipt

Используем дополнительный плагин. Его нужно сразу подключить после подключения jQuery.

Объявим переменные:


var $ac_background  = $('#ac_background'),
$ac_bgimage     = $ac_background.find('.ac_bgimage'),
$ac_loading     = $ac_background.find('.ac_loading'),

$ac_content     = $('#ac_content'),
$title          = $ac_content.find('h1'),
$menu           = $ac_content.find('.ac_menu'),
$mainNav        = $menu.find('ul:first'),
$menuItems      = $mainNav.children('li'),
totalItems      = $menuItems.length,
$ItemImages     = new Array();


Загружаем изображения так, чтобы добавились все ссылки и объявим текущее изображение:


$menuItems.each(function(i) {
    $ItemImages.push($(this).children('a:first').attr('href'));
});
$ItemImages.push($ac_bgimage.attr('src'));

А теперь приступим к нашей главной функции:

var Menu            = (function(){
    var init                = function() {
        loadPage();
        initWindowEvent();
    },
    loadPage            = function() {
        /*
            1- загружает все фоновые и другие изображения;
            2- отображает фоновое изображение;
            3- скрывает и открывает меню;
            4- отображает пункты меню;
            5- инициализирует события, связанные с пунктами меню
         */
        $ac_loading.show(); //отображение иконки загрузки
        $.when(loadImages()).done(function(){
            $.when(showBGImage()).done(function(){
                //скрывает иконку загрузки
                $ac_loading.hide();
                $.when(slideOutMenu()).done(function(){
                        $.when(toggleMenuItems('up')).done(function(){
                        initEventsSubMenu();
                    });
                });
            });
        });
    },
    showBGImage         = function() {
        return $.Deferred(
        function(dfd) {
            //подсчитывает размеры изображения
            adjustImageSize($ac_bgimage);
            $ac_bgimage.fadeIn(1000, dfd.resolve);
        }
    ).promise();
    },
    slideOutMenu        = function() {
        /* подсчитывает новую ширину меню */
        var new_w   = $(window).width() - $title.outerWidth(true);
        return $.Deferred(
        function(dfd) {
            //скрывает меню
            $menu.stop()
            .animate({
                width   : new_w + 'px'
            }, 700, dfd.resolve);
        }
    ).promise();
    },
        /* скрывает / отображает пункт меню */
        toggleMenuItems     = function(dir) {
        return $.Deferred(
        function(dfd) {
            /*
            скрывает / отображает пункты меню.
            каждый раз разная анимация.
            */
            $menuItems.each(function(i) {
                        var $el_title   = $(this).children('a:first'),
                            marginTop, opacity, easing;
                        if(dir === 'up'){
                            marginTop   = '0px';
                            opacity     = 1;
                            easing      = 'easeOutBack';
                        }
                        else if(dir === 'down'){
                            marginTop   = '60px';
                            opacity     = 0;
                            easing      = 'easeInBack';
        }
                $el_title.stop()
                .animate({
                                    marginTop   : marginTop,
                                    opacity     : opacity
                                 }, 200 + i * 200 , easing, function(){
                    if(i === totalItems - 1)
                        dfd.resolve();
                });
            });
        }
    ).promise();
    },
    initEventsSubMenu   = function() {
        $menuItems.each(function(i) {
            var $item       = $(this), // 

            $el_title   = $item.children('a:first'),
            el_image    = $el_title.attr('href'),
            $sub_menu   = $item.find('.ac_subitem'),
            $ac_close   = $sub_menu.find('.ac_close');

            /* пользователь кликает по пункту меню */
            $el_title.bind('click.Menu', function(e) {
                    $.when(toggleMenuItems('down')).done(function(){
                    openSubMenu($item, $sub_menu, el_image);
                });
                return false;
            });
            /* контент скрывается */
            $ac_close.bind('click.Menu', function(e) {
                closeSubMenu($sub_menu);
                return false;
            });
        });
    },
    openSubMenu         = function($item, $sub_menu, el_image) {
        $sub_menu.stop()
        .animate({
            height      : '400px',
            marginTop   : '-200px'
        }, 400, function() {
            //the bg image changes
            showItemImage(el_image);
        });
    },
    /* меняется фоновое изображение */
    showItemImage       = function(source) {
        //если это текущее изображение, то вернет 0
        if($ac_bgimage.attr('src') === source)
            return false;

        var $itemImage = $('');
        $itemImage.insertBefore($ac_bgimage);
        adjustImageSize($itemImage);
        $ac_bgimage.fadeOut(1500, function() {
            $(this).remove();
            $ac_bgimage = $itemImage;
        });
        $itemImage.fadeIn(1500);
    },
    closeSubMenu        = function($sub_menu) {
        $sub_menu.stop()
        .animate({
            height      : '0px',
            marginTop   : '0px'
        }, 400, function() {
            //отображение элементов
                        toggleMenuItems('up');
        });
    },
    /*
    on window resize, ajust the bg image dimentions,
    and recalculate the menus width
    */
    initWindowEvent     = function() {
        /* назначает ширину фонового изображения */
        $(window).bind('resize.Menu' , function(e) {
            adjustImageSize($ac_bgimage);
            /* считает новую ширину меню */
            var new_w   = $(window).width() - $title.outerWidth(true);
            $menu.css('width', new_w + 'px');
        });
    },
    /* расширяет изображение и располагает его по центру */
    adjustImageSize     = function($img) {
        var w_w = $(window).width(),
        w_h = $(window).height(),
        r_w = w_h / w_w,
        i_w = $img.width(),
        i_h = $img.height(),
        r_i = i_h / i_w,
        new_w,new_h,
        new_left,new_top;

        if(r_w > r_i){
            new_h   = w_h;
            new_w   = w_h / r_i;
        }
        else{
            new_h   = w_w * r_i;
            new_w   = w_w;
        }

        $img.css({
            width   : new_w + 'px',
            height  : new_h + 'px',
            left    : (w_w - new_w) / 2 + 'px',
            top     : (w_h - new_h) / 2 + 'px'
        });
    },
    /* загружает все изображения */
    loadImages          = function() {
        return $.Deferred(
        function(dfd) {
            var total_images    = $ItemImages.length,
            loaded          = 0;
            for(var i = 0; i < total_images; ++i){
                $('').load(function() {
                    ++loaded;
                    if(loaded === total_images)
                        dfd.resolve();
                }).attr('src' , $ItemImages[i]);
            }
        }
    ).promise();
    };

    return {
        init : init
    };
})();

/*
вызов метода init
 */
Menu.init();


Все. Вы научились делать анимированное меню.

Категория: HTML и DHTML, JQuery, Дизайн, Для сайта Теги: 

Популярные записи:

Всплывающие отзывы гостей сайта Всплывающие отзывы гостей сайта
Форма обратной связи с аттачами Форма обратной связи с аттачами
Создание виртуальной клавиатуры Создание виртуальной клавиатуры
Загрузка API Google Map по запросу Загрузка API Google Map по запросу

Один комментарий "Анимированное меню с помощью jQuery"

  1. kira:

    а где же демо

Оставить комментарий или два

Отправить коментарий

Test

Яндекс.Метрика