chevron-left chevron-right

[CSS][jQuery] Efektowne menu z tłami

W dzisiejszym artykule przedstawię sposób na zbudowanie bardzo efektownego menu przypominającego animacje Flash. Głównym zamierzeniem tego efektu jest posiadanie trzech obrazków jako tło pod każdą osobną pozycją menu, który to obrazek się zmienia zależnie od tego, które pozycja z menu zostanie wskazana.
Moim zdaniem taki efekt można skutecznie wykorzystać na stronach portfolio czy stronach studiów fotograficznych.

Najpierw należy stworzyć strukturę takiego menu. W tym przypadku menu będzie wyglądało w następujący sposób:

<div id="kontener">
<ul class="menu" id="menu">
<li class="bg1" style="background-position:0 0;">
      <a id="bg1" href="#">Miasto</a>
<ul class="podmenu1" style="background-position:0 0;">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
<li class="bg1" style="background-position:-266px 0px;">
         <a id="bg2" href="#">Wąż</a>
<ul class="podmenu2" style="background-position:-266px 0;">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
<li class="last bg1" style="background-position:-532px 0px;">
         <a id="bg3" href="#">Niebo</a>
<ul class="podmenu3" style="background-position:-266px 0;">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</li>
</ul>
</div>

Dla uproszczenia wykorzystałem zagnieżdżone style CSS. To nie jest dobra praktyka webmasterska, ale musisz mi wybaczyć taki krok.

Kolejnym krokiem jest zdefiniowanie stylu CSS dla naszego menu:

#kontener {
    font-size: 15px;
    font-style: normal;
    font-weight: normal;
    text-transform: uppercase;
    letter-spacing: normal;
    line-height: 1.45em;
    position: relative;
    margin: 20px auto;
    height: 542px;
    width: 797px;
    background-position: 0 0;
    background-repeat: no-repeat;
    background-color: transparent;
}
ul.menu {
    list-style: none;
    width: 797px;
}
ul.menu > li {
    float: left;
    width: 265px;
    height: 542px;
    border-right: 1px solid #777;
    background-repeat: no-repeat;
    background-color: transparent;
}
ul.menu > li.last {
    border: none;
}
.bg1 {
    background-image: url(../images/1.jpg);
}
.bg2 {
    background-image: url(../images/2.jpg);
}
.bg3 {
    background-image: url(../images/3.jpg);
}
ul.menu > li > a {
    float: left;
    width: 265px;
    height: 50px;
    margin-top: 450px;
    text-align: center;
    line-height: 50px;
    color: #ddd;
    background-color: #333;
    letter-spacing: 1px;
    cursor: pointer;
    text-decoration: none;
    text-shadow: 0px 0px 1px #fff;
}
ul.menu > li ul {
    list-style: none;
    float: left;
    margin-top: -180px;
    width: 100%;
    height: 110px;
    padding-top: 20px;
    background-repeat: no-repeat;
    background-color: transparent;
}
ul.menu > li ul li {
    display: none;
}
ul.menu > li ul.podmenu1 {
    background-image: url(../images/bg1.png);
}
ul.menu > li ul.podmenu2 {
    background-image: url(../images/bg2.png);
}
ul.menu > li ul.podmenu3 {
    background-image: url(../images/bg3.png);
}
ul.menu > li ul li a {
    color: #fff;
    text-decoration: none;
    line-height: 30px;
    margin-left: 20px;
    text-shadow: 1px 1px 1px #444;
    font-size: 11px;
}
ul.menu > li ul.podmenu1 li {
    display: block;
}
ul.menu > li ul li a:hover {
    border-bottom: 1px dotted #fff;
}

Ostatnim krokiem jest stworzenie skryptu JavaScript, który będzie odpowiednio animował nasze menu.
Szczegóły tego kodu są opisane w komentarzach w kodzie.

$(function() {
	/* pozycja znacznika
<li> który jest obecnie pokazany */
	var stanObecny = 0;
 
	var stanZaladowany  = 0;
	for(var i = 1; i &lt;4; ++i)
		$('<img />').load(function(){
			++stanZaladowany;
			if(stanZaladowany == 3){
				$('#bg1,#bg2,#bg3').mouseover(function(e){
 
					var $this = $(this);
					/* jeśli najedziemy na pokazany znacznik to nic nie robi */
					if($this.parent().index() == stanObecny)
						return;
 
					/* obiektami najazdu są bg1 lub bg2 lub bg3, zależnie od tego który wskażemy kursorem */
					var obiektMenu = e.target.id;
 
					/*
					tutaj ustawiamy tło podmenu.
					Ustawiamy kierunek ruchu animacji zależnie od tego z której strony
					najedziemy kursorem.
					Jeśli najedziemy z lewej strony obrazka to animacja będzie
					szła od prawej do lewej, a jeśli z prawej strony najedziemy
					to animacja będzie szła od lewej do prawej
					 */
					if(obiektMenu == 'bg1' || stanObecny == 2)
						$('#menu .podmenu'+parseInt(stanObecny+1)).stop().animate({backgroundPosition:"(-266px 0)"},300,function(){
							$(this).find('li').hide();
						});
					else
						$('#menu .podmenu'+parseInt(stanObecny+1)).stop().animate({backgroundPosition:"(266px 0)"},300,function(){
							$(this).find('li').hide();
						});
 
					if(obiektMenu == 'bg1' || stanObecny == 2){
						/* animacja od lewej do prawej */
						$('#menu > li').animate({backgroundPosition:"(-800px 0)"},0).removeClass('bg1 bg2 bg3').addClass(obiektMenu);
						move(1,obiektMenu);
					}
					else{
						/* animacja od prawej do lewej */
						$('#menu > li').animate({backgroundPosition:"(800px 0)"},0).removeClass('bg1 bg2 bg3').addClass(obiektMenu);
						move(0,obiektMenu);
					}
 
					/*
					Część środkowa menu, też powinna ulec animacji, gdy będziemy przejeżdżać
					kursorem nad częścią środkową.
					Animacja ma być zależna od kierunku najazdu.
					To jest ważne w przypadku przechodzenia od pierwszego do ostatniego lelemntu menu
					lub na odwrót.
					 */
					if(stanObecny == 2 && obiektMenu == 'bg1'){
						$('#menu .podmenu'+parseInt(stanObecny)).stop().animate({backgroundPosition:"(-266px 0)"},300);
					}
					if(stanObecny == 0 && obiektMenu == 'bg3'){
						$('#menu .podmenu'+parseInt(stanObecny+2)).stop().animate({backgroundPosition:"(266px 0)"},300);
					}
 
					/* zmień obecny element */
					stanObecny = $this.parent().index();
 
					/* nakładanie tła dla podmenu */
 
					$('#menu .podmenu'+parseInt(stanObecny+1)).stop().animate({backgroundPosition:"(0 0)"},300,function(){
						$(this).find('li').fadeIn();
					});
				});
			}
		}).attr('src', 'images/'+i+'.jpg');
 
		 function move(dir,obiektMenu){
			  if(dir){
					$('#bg1').parent().stop().animate({backgroundPosition:"(0 0)"},200);
					$('#bg2').parent().stop().animate({backgroundPosition:"(-266px 0)"},300);
					$('#bg3').parent().stop().animate({backgroundPosition:"(-532px 0)"},400,function(){
						 $('#kontener').removeClass('bg1 bg2 bg3').addClass(obiektMenu);
					});
			  }
			  else{
					$('#bg1').parent().stop().animate({backgroundPosition:"(0 0)"},400,function(){
						 $('#kontener').removeClass('bg1 bg2 bg3').addClass(obiektMenu);
					});
					$('#bg2').parent().stop().animate({backgroundPosition:"(-266px 0)"},300);
					$('#bg3').parent().stop().animate({backgroundPosition:"(-532px 0)"},200);
			  }
		 }
	});
</li>

Należy pamiętać o tym, aby dodać do naszego pliku HTML bibliotekę jQuery oraz plugin jquery.bgpos. Dzięki temu nasz efekt zadziała tak jak tego chcemy.

To byłoby wszystko, jeśli chodzi o ten artykuł.
Działający przykład możesz zobaczyć pod tym linkiem: efektowne menu z przewijanymi tłami


Tak jak obiecałem, dorzucam spakowaną wersję demo tego efektu do pobrania: pobierz efektowne menu z tłami