Ten wpis ma 15 lat. Od tego czasu przeglądarki i narzędzia mogły się zmienić, więc zanim użyjesz kodu, sprawdź go z aktualną dokumentacją.
W dzisiejszym artykule, przedstawię Ci sposób na stworzenie efektownego menu bazującego na kwadratach. Bardzo często podobne menu można spotkać na stronach zbudowanych w oparciu o Flash. Ten poradnik przedstawi Ci sposób na zbudowanie tego samego efektu za pomocą CSS i jQuery.
Na początek należy przygotować sobie odpowiednią strukturę pliku HTML, która będzie się opierała na jednym głównym kontenerze z wieloma mniejszymi kontenerami (divami) w środku. Niektóre z nich będą zawierały linki i treści, a niektóre będą zawierały predefiniowane pozycje obrazka, dzięki czemu uzyskamy efekt mozaiki z jednego obrazka. Wszystkie elementy są pozycjonowane absolutnie. Niektóre z elementów zawierają tzw. style wewnętrzne, nie zdefiniowane w sekcji stylów CSS w HEAD. Ma to na celu ułatwienie pozycjonowania elementów mozaiki.
.boxy{width:350px;height:350px;margin:200pxauto;position:relative;}.boxy> div {position:absolute;width:90px;height:90px;text-align:center;border:2pxsolid#a3a3a3;overflow:hidden;background-color:#f7f7f7;
-moz-box-shadow:0px0px3px#555;
-webkit-box-shadow:0px0px3px#555;box-shadow:0px0px3px#555;background-position:centercenter;z-index:999;}.boxy div a {text-transform:uppercase;font-size:16px;font-weight:bold;letter-spacing:-1px;display:block;line-height:90px;text-decoration:none;color:#fff;background:#91EF4Aurl(bgItem.jpg)repeat-xtopleft;outline:none;text-shadow:1px1px1px#888;
-moz-box-shadow:1px1px3px#777;
-webkit-box-shadow:1px1px3px#777;box-shadow:1px1px3px#777;}.boxy div.boxcontent{width:334px;height:246px;text-align:left;padding:10px;font-size:16px;background-color:#000;border:2pxsolid#fff;margin:10px0px0px10px;text-shadow:1px1px1px#000;
-moz-box-shadow:1px1px3px#777;
-webkit-box-shadow:1px1px3px#777;box-shadow:1px1px3px#777;opacity:0.8;display:none;color:#fff;}.bg1,.bg2,.bg3,.bg4{background-repeat:no-repeat;}.bg1{background-image:url(bg1.jpg);}.bg2{background-image:url(bg2.jpg);}.bg3{background-image:url(bg3.jpg);}.bg4{background-image:url(bg4.jpg);}.bg5{background-image:url(bg5.jpg);}
Nasz główny kontener: .boxy, jest wycentrowany na stronie i pozycjonowany relatywnie. Kontenery wewnątrz kontenera .boxy zawierają jednolity styl. Są pozycjonowane absolutnie i mają dodany przyjemny w odbiorze efekt cienia.
Treść wybranych kontenerów ujawnia się w momencie kliknięcia w link, dlatego wstępnie kontenery z treścią są ukryte.
Na początek, należy załadować bibliotekę jQuery oraz jQuery.UI. Mając je załadowane możemy przejść do tworzenia docelowego efektu.
Aby uzyskać efekt "swobodnego lotu" musimy zapisać początkowe pozycje każdego z kontenerów, dzięki czemu będziemy mogli przywrócić ich pozycje za pomocą kliknięcia w element menu.
Kiedy klikniemy w element menu, następuje losowa animacja pozycji kontenerów a kliknięty element rozwija się do maksymalnych zdefiniowanych rozmiarów głównego kontenera. Ponadto, animuje się treść klikniętego kontenera.
Jeśli klikniemy nagłówek rozwiniętego kontenera, to następuje powrót do domyślnego widoku menu.
$(function(){/* obiekt zapisujący pozycje konenterów */var divinfo ={"initial":[]};/* indeks wybranego/klikniętego kontenera */var current =-1;/* zapisujemy index, pozycję top, pozycję left każdego kontenera */
$('#boxy > div').each(function(){var $this = $(this);var initial ={'index': $this.index(),'top': $this.css('top'),'left': $this.css('left')};
divinfo.initial.push(initial);});/* wywoływanie zdarzenia po kliknięciu w kontener */
$('#boxy a').bind('click',function(e){var $this = $(this);var $currentBox = $this.parent();/* ustaw z-index mniejszy niż reszty kontenerów,
aby zobaczyć animację innych kontenerów na górze*/
$currentBox.css('z-index','1');/* jeśli klikniemy na rozwinięty kontener: */if(current == $currentBox.index()){/* przywróć widok domyślny (zmniejsz szerokość, wysokość
i wyzeruj pozycje top i left)
domyślne wartości są zapisane w obiekcie divinfo*/
$currentBox.stop().animate({'top': divinfo.initial[$currentBox.index()].top,'left': divinfo.initial[$currentBox.index()].left,'width':'90px','height':'90px'},800,'easeOutBack').find('.boxcontent').fadeOut();
$('#boxy > div').not($currentBox).each(function(){var $ele = $(this);var elemTop = divinfo.initial[$ele.index()].top;var elemLeft = divinfo.initial[$ele.index()].left;
$ele.stop().show().animate({'top': elemTop,'left': elemLeft,'opacity':1},800);});
current =-1;}/* jeśli klikniemy na mały kontener : */else{/* losowo animuj inne konentenery. */
$('#boxy > div').not($currentBox).each(function(){var $ele = $(this);
$ele.stop().animate({'top':(Math.floor(Math.random()*601)-150)+'px','left':(Math.floor(Math.random()*601)-150)+'px','opacity':0},800,function(){
$(this).hide();});});/* powiększ kliknięty, a także animuj kontener z treścią */var newwidth =379;var newheight =379;
$currentBox.stop().animate({'top':'0px','left':'0px','width': newwidth +'px','height': newheight+'px'},800,'easeOutBack',function(){
current = $currentBox.index();
$(this).find('.boxcontent').fadeIn();});}
e.preventDefault();});});
$(function() {
/* obiekt zapisujący pozycje konenterów */
var divinfo = {"initial": []};
/* indeks wybranego/klikniętego kontenera */
var current = -1;
/* zapisujemy index, pozycję top, pozycję left każdego kontenera */
$('#boxy > div').each(function(){
var $this = $(this);
var initial = {
'index' : $this.index(),
'top' : $this.css('top'),
'left' : $this.css('left')
};
divinfo.initial.push(initial);
});
/* wywoływanie zdarzenia po kliknięciu w kontener */
$('#boxy a').bind('click',function(e){
var $this = $(this);
var $currentBox = $this.parent();
/* ustaw z-index mniejszy niż reszty kontenerów,
aby zobaczyć animację innych kontenerów na górze*/
$currentBox.css('z-index','1');
/* jeśli klikniemy na rozwinięty kontener: */
if(current == $currentBox.index()){
/* przywróć widok domyślny (zmniejsz szerokość, wysokość
i wyzeruj pozycje top i left)
domyślne wartości są zapisane w obiekcie divinfo*/
$currentBox.stop().animate({
'top' : divinfo.initial[$currentBox.index()].top,
'left' : divinfo.initial[$currentBox.index()].left,
'width' : '90px',
'height' : '90px'
},800,'easeOutBack').find('.boxcontent').fadeOut();
$('#boxy > div').not($currentBox).each(function(){
var $ele = $(this);
var elemTop = divinfo.initial[$ele.index()].top;
var elemLeft = divinfo.initial[$ele.index()].left;
$ele.stop().show().animate({
'top' : elemTop,
'left' : elemLeft,
'opacity' : 1
},800);
});
current = -1;
}
/* jeśli klikniemy na mały kontener : */
else{
/* losowo animuj inne konentenery. */
$('#boxy > div').not($currentBox).each(function(){
var $ele = $(this);
$ele.stop().animate({
'top' : (Math.floor(Math.random()*601) - 150) +'px',
'left': (Math.floor(Math.random()*601) - 150) +'px',
'opacity':0
},800,function(){
$(this).hide();
});
});
/* powiększ kliknięty, a także animuj kontener z treścią */
var newwidth = 379;
var newheight = 379;
$currentBox.stop().animate({
'top' : '0px',
'left' : '0px',
'width' : newwidth +'px',
'height': newheight+'px'
},800,'easeOutBack',function(){
current = $currentBox.index();
$(this).find('.boxcontent').fadeIn();
});
}
e.preventDefault();
});
});
Wpis w oryginalnej wersji można znaleźć na stronie. Jego przedruk został napisany przeze mnie, dzięki współpracy z autorem.
Demo z tego artykułu można zobaczyć w tym miejscu: jQuery menu z kwadratami
Piszę na tym blogu od 2009 roku, a strony i aplikacje webowe tworzę zawodowo od 14 lat. Obecnie w Bishop Fox prowadzę frontend platformy Cosmos, od samego początku projektu. Wcześniej pracowałem m.in. w OLX, KUDO, Auto1 i eZ Systems. Piszę tu o tym, czego nauczyłem się w praktyce: o JavaScripcie, TypeScripcie, Reakcie, CSS-ie i architekturze frontendu. Występowałem też jako prelegent na konferencjach w Polsce i Europie. Masz pytanie albo pomysł na wpis? Daj znać!