23
Czerwiec
wtorek, 23 Czerwiec 2009

Tworzymy galerie w jQuery

Galerii wykorzystujących jQuery jest całkiem sporo, najbardziej polecam http://sorgalla.com/jcarousel/. Warto natomiast spróbować napisać coś swojego, prostszego choćby po to, żeby nieco lepiej poznać ten framework, albo można też zrobić coś innego jak na przykład to: http://www.reboo.pl/foty/

Na początek potrzebujemy dosyć prosty plik HTML z kilkoma elementami mniej więcej o takiej strukturze:

<div id="content">
 <div id="prev"></div>
  <div id="gallery">
   <div class="thumb"><img src="files/Audi-R8_2007_1024x768_wallpaper_04.jpg" alt="" /></div>
   <div class="thumb"><img src="files/Audi-R8_2007_1024x768_wallpaper_07.jpg" alt="" /></div>
   <div class="thumb"><img src="files/Audi-R8_2007_1024x768_wallpaper_0f.jpg" alt="" /></div>
   ...
  </div>
 <div id="next"></div>
</div>

Do wczytania plików z katalogu i automatycznego przeskalowania ich można użyć skryptu loader.php, który korzysta z klasy Image opisywanej w poście http://www.reboo.pl/2009/05/10/image-resizer/

Jak można się domyślić, jest to kontener z obrazkami oraz guziki poprzedni/następny. Plik CSS jest banalnie prosty, ustawia tylko te buttony i centruje galerie.

Ważniejszy jest natomiast JavaScript. Na początek niech będzie to klasa Gallery z kilkoma atrybutami:

var Gallery = {
	galleryId: false, 

	prevId: false, 

	nextId: false,

	count: 0,

	current: 0,

	previous: 0,

	imgs: false,

	animates: false
};

Są to kolejno: ID galerii, ID buttona poprzedni/następny, liczba elementów, aktualny element, tablica wszystkich elementów oraz czy galeria teraz się animuje. Efekt jaki chcemy uzyskać w pierwszej galerii to pojawianie się kolejnych obrazów z efektem fade in.

Na początek ustawienia i utworzenie galerii:

	create: function(galleryId, prevId, nextId, current)
	{
		this.galleryId=galleryId;
		this.prevId=prevId;
		this.nextId=nextId;
		this.imgs=$("#"+this.galleryId+" .thumb");
		this.count=this.imgs.length;
	    if (typeof current != 'undefined')
	    {
	    	this.current=current-1;
	    	if (this.current>this.count)
	    		this.current=0;
	    }
	    $("#"+this.prevId).click(function(){
	    	Gallery.prev();
	    });
	    $("#"+this.nextId).click(function(){
	    	Gallery.next();
	    });
	    this.setup();
	    this.show();
	},

	setup: function()
	{
		$("#"+this.galleryId).css('position','relative');
		$("#"+this.galleryId+" .thumb").css('display','none');
	}

Funkcja ta ustawia atrybuty klasy, przypisuje zdarzenia do guzików, liczy wszystkie elementy wywołuje funkcję setup, która jest właściwie kontynuacją inicjalizacji, ale będzie się nieco różnić w innych przykładach. W tym akurat wszystkie elementy galerii są na początku ukrywane, a następnie pokazywany pierwszy za pomocą funkcji show, którą za chwilę zaimplementujemy.

Teraz funkcje przestawiające wskaźnik aktualnego elementu:

	next: function()
	{
		if (!this.animates)
		{
			if ((this.current+1)<this.count)
			{
				this.animates=true;
				this.previous=this.current;
				this.current++;
				this.show();
			}
		}
	},

	prev: function()
	{
		if (!this.animates)
		{
			if ((this.current-1)>=0)
			{
				this.animates=true;
				this.previous=this.current;
				this.current--;
				this.show();
			}
		}
	},

Sprawdzają tylko czy akurat galeria się nie animuje i czy jest poprzedni lub następny element, jeśli tak o przesuwają wskaźnik i ustawiają atrybut animates na true.
Teraz najważniejszą funkcja wyświetlająca aktualny obraz:

	show: function()
	{
		$(this.imgs[this.current]).css({'position': 'absolute', 'top': 0, 'left': 0}).fadeIn("slow", function(){
			$(Gallery.imgs[Gallery.current]).css('position', 'static');
    		$(Gallery.imgs[Gallery.previous]).css('display', 'none');
    		Gallery.animates=false;
    	}

Aktualny obraz jest ustawiany ponad poprzednim dzięki stylowi position: absolute, a następnie wywoływany jest na nim efekt fadeIn, a po jego zakończeniu wywoływana jest funkcja callbackowa, która z powrotem przypisuje mu pozycję statyczną. Ukrywany jest też poprzedni obraz. Uzyskany efekt można zobaczyć tutaj: http://www.reboo.pl/files/demos/galleries2/gallery1.php

Żeby inicjalizować galerię wystarczy w zdarzeniu window ready wywołać funkcję cereate z odpowiednimi parametrami:

$(window).ready(function(){
	Gallery.create('gallery', 'prev', 'next', 3);
});

Następny przykład będzie się różnić w zasadzie tylko efektem, tym razem będzie to slide, czyli obrazki będą przesuwać się w prawo lub lewo.

W tym celu do funkcji create trzeba dodać szerokość obrazów i zmienić setup:

	setup: function()
	{
		h=$("#"+this.galleryId).html();
		$("#"+this.galleryId).html('<div id="gallery-container">'+h+'</div>').css('overflow', 'hidden');
		$("#gallery-container").css('width', this.count * this.width );
		$("#"+this.galleryId+" .thumb").css('float', 'left');
		$("#gallery-container").css({'margin-left': (-(this.current * this.width))});

		if (this.current==this.count)
			$("#"+this.nextId).css('cursor', 'default').addClass('disabled');
		if (this.current==0)
			$("#"+this.prevId).css('cursor', 'default').addClass('disabled');
	},

Wstawiany jest tutaj dodatkowy kontener gallery-container o szerokości sumy wszystkich obrazów. Będzie on później przesuwany względem elementu nadrzędnego. Dodatkowo do guzików dodawana jest klasa disabled i zmieniany jest kursow jeśli aktualnym elementem jest pierwszy lub ostatni. Ten sam kod można użyć w funkcjach prev i next. Teraz zmiany w show:

	show: function()
	{
		$("#gallery-container").animate({'marginLeft': (-(this.current * this.width))}, "def", "swing", function(){
    		Gallery.animates=false;
    	}

Działa to takjak napisałem wyżej, użyty jest esaing typu swing, żeby dodać nieco spowolnienia na początku. Demo można zobaczyć tutaj: http://www.reboo.pl/files/demos/galleries2/gallery2.php

Trzecią modyfikacją będzie pokazanie nie jednego a trzech obrazów. W tym celu do funkcji create należy dodać parametr shown definiujący ilość aktualnie pokazywanych elementów i przypisać go do atrybutu oraz zmienić setup przez dodanie na końcu kodu:

		w=$("#"+this.galleryId).width();
		$("#"+this.galleryId).width(this.width*this.shown);
		$("#content").width(this.width*this.shown);

Funkcje zmieniające aktualną fotkę także należy nieco zmodyfikować przez zmianę ograniczeń.

			if ((this.current+1)<=(this.count-this.shown))
			{
				...
			}

Uzyskany efekt znajduje się tutaj: http://www.reboo.pl/files/demos/galleries2/gallery3.php

Cały kod tych trzech przykładów można pobrać z: http://www.reboo.pl/files/download/galleries2.zip

Zapraszam także jeszcze raz do zoabczenia mojej galerii zdjęć wykorzystującej podobne rozwiązania jak tutaj na http://www.reboo.pl/foty/

wtorek, 23 Czerwiec 2009 
Kategoria: CSS, JavaScript, jQuery
Możesz śledzić ten wpis przez RSS 2.0 lub dodać komentarz.

Liczba komentarzy: 4

  1. witam,
    bardzo fajny tutorial,
    mam pytanie odnośnie jego:
    jak to samo wykonać na zdjęciach czytanych z bazy danych?

  2. Myślę, że najprościej jest napisać jakiś skrypt, który czyta zdjęcie z bazy i przesyła je do przeglądarki. W sumie to nie ma znaczenia, czy zdjęcia są z zwykłego pliku, czy przesyłane z skryptu.

  3. Jak zrobić żeby był autoscroling?

  4. Można zastosować Smooth Scroll np. taki jak ten: http://blog.medianotions.de/en/articles/2009/smoothscroll-for-jquery

Zostaw komentarz

Home Home O mnie O mnie Efekty
JavaScript, jQuery, AJAX
Efekty
Inspiracje
Ciekawe strony WWW
Inspiracje
Programowanie
CakePHP, PHP, MySQL
Programowanie
SEO
Wyszukiwarki
SEO
Web Building
HTML i CSS
Web Building
Projekty Linki Kontakt Kontakt