Przejdź do treści

Galeria zdjęć

Klasyczna galeria zdjęć

Na wielu stronach w Internecie można spotkać galerię zdjęć, stosowaną do przedstawienia kolekcji zdjęć, zwykle o dużych rozmiarach. Najczęściej jest ona tworzona w ten sposób, że na głównej stronie umieszcza się pomniejszone kopie obrazków oraz odsyłacze, po kliknięciu których następuje wczytanie obrazka w pełnych rozmiarach. Pozwala to uchronić się od wczytywania wszystkich dużych obrazków jednocześnie (użytkownik powiększa tylko te, które mu odpowiadają), a także zachowuje estetykę strony.

Uwaga! Miniaturki grafik muszą być pomniejszone fizycznie, tzn. nie mogą to być oryginalne duże obrazki ze zmniejszonymi rozmiarami wyświetlania za pomocą atrybutów WIDTH oraz HEIGHT. Tylko wstawienie naprawdę pomniejszonych obrazków uchroni od niepotrzebnego wczytywania dużych plików.

Zmniejszenia wymiarów obrazka można dokonać praktycznie w każdym programie graficznym. Najczęściej ustala się takie same rozmiary dla wszystkich miniatur, ponieważ ułatwia to utrzymanie estetyki strony. Obrazki w galerii zwykle ustawia się w komórkach tabeli (najczęściej bez obramowania), dzięki czemu można je dokładnie ustawić w rzędach i kolumnach. Jeżeli zamierzasz umieścić na swojej stronie obszerniejszą galerię grafik, zaleca się podzielenie jej na kilka części i stworzenie kilku podstron z miniaturkami.

Wczytanie oryginalnego dużego obrazka następuje najczęściej po kliknięciu bezpośrednio jego miniaturki. Aby zastosować taki efekt, należy użyć odsyłacza obrazkowego (podstawowego). Prawie zawsze stosuje się również atrybut target="_blank", który powoduje otwarcie nowego okna przeglądarki:

<a target="_blank" href="ścieżka do dużego obrazka"><img src="ścieżka do pliku miniaturki obrazka" alt="Tekst alternatywny" border="0" /></a>

Większość nowych przeglądarek potrafi automatycznie otworzyć obrazek w nowym oknie, jednak obraz najczęściej nie jest wtedy wyśrodkowany i nie ma możliwości otwarcia go w nowym oknie bez pasków menu, narzędzi itd. Natomiast starsze przeglądarki po kliknieciu przez użytkownika takiego linka często najpierw wyświetlały okienko z pytaniem co zrobić z obrazkiem, tzn. otworzyć czy zapisać, a po wybraniu pierwszej opcji, następowało wczytanie pliku w zewnętrznym programie (jeśli użytkownik miał taki zainstalowany), co mogło potrwać kilka sekund i było trochę irytujące w przypadku dużej ilości zdjęć. Dlatego w klasycznej galerii zdjęć zwykle zamiast podawać link bezpośrednio do dużego obrazka, tworzy się dodatkową stronę z grafiką wstawioną na niej za pomocą znacznika <img /> i dopiero taki dokument podaje się w linku:

<a target="_blank" href="ścieżka do strony z dużym obrazkiem"><img src="ścieżka do pliku miniaturki obrazka" alt="Tekst alternatywny" border="0" /></a>

Jak łatwo zauważyć, aby stworzyć klasyczną galerię zdjęć, trzeba napisać tyle stron, ile mamy obrazków - po jednej dla każdego dużego egzemplarza (a nawet co najmniej o jedną więcej).

Istnieją specjalne programy, które potrafią stworzyć statyczną galerię grafik. Wystarczy wybrać zdjęcia za pomocą selektora plików, a program automatycznie wygeneruje miniatury zdjęć oraz wszystkie potrzebne dokumenty HTML.

Pewną niedogodnością w przypadku programów tworzących statyczne galerie, może jednak być utrudniona aktualizacja takiej galerii. Dodanie choćby jednego nowego zdjęcia zwykle będzie wiązało się z generowaniem galerii na nowo.

Skrypt galerii

Stosując specjalny skrypt, który automatycznie otwiera pliki w nowym oknie bez potrzeby tworzenia dodatkowych stron, można zautomatyzować tworzenie galerii. Ponadto aktualizacja nie będzie w tym przypadku utrudniona - dodanie nowego zdjęcia będzie się wiązało tylko z dopisaniem jednej dodatkowej linijki bez potrzebny tworzenia całej galerii od nowa.

Wymagana wiedza:

Aby wstawić na stronę skrypt galerii zdjęć, należy zapisać przedstawiony poniżej kod w dowolnym pliku z rozszerzeniem *.js - np. galeria.js:

/**
 * @author Sławomir Kokłowski {@link http://www.kurshtml.edu.pl}
 * @copyright NIE usuwaj tego komentarza! (Do NOT remove this comment!)
 */

function Galeria(id, zdjecia, css, ochrona, zaladuj)
{
	this.kolumny = 2;
	this.naStronie = 10;
	
	
	this.id = id;
	this.zdjecia = zdjecia;
	this.ochrona = typeof ochrona != 'undefined' ? ochrona : false;
	this.css = css;
	
	if (typeof zaladuj != 'undefined' && zaladuj)
	{
		for (var i = 0; i < this.zdjecia.length; i++)
		{
			new Image().src = this.zdjecia[i][0];
		}
	}
	
	this.wyswietl = function(strona)
	{
		if (typeof strona == 'undefined') strona = 1;
		var html = '';
		
		for (var i = start_ = (strona - 1) * this.naStronie, stop_ = Math.min(start_ + this.naStronie, this.zdjecia.length); i < stop_; i++)
		{
			if (i > start_ && !(i % this.kolumny)) html += '</tr><tr>';
			html +=
				'<td>' +
					'<a href="' + (this.ochrona ? 'javascript:void(0)' : this.zdjecia[i][1]) + '" onclick="return !' + this.id + '.pokaz(' + i + ')" onkeypress="return !' + this.id + '.pokaz(' + i + ')"><img src="' + this.zdjecia[i][0] + '" alt=""' + (this.ochrona ? ' onmousedown="return false" oncontextmenu="return false" onselectstart="return false" onselect="return false" oncopy="return false" ondragstart="return false" ondrag="return false" galleryimg="no"' : '') + ' /></a>' +
					(typeof this.zdjecia[i][2] != 'undefined' ? '<div>' + this.zdjecia[i][2] + '</div>' : '') +
				'</td>';
		}
		if (html) html = '<table><tr>' + html + '</tr></table>';
		
		if (this.zdjecia.length > this.naStronie)
		{
			html += '<div class="stronicowanie">';
			if (strona > 1) html += '<a href="javascript:void(0)" onclick="' + this.id + '.wyswietl(' + (strona - 1) + '); return false" onkeypress="' + this.id + '.wyswietl(' + (strona - 1) + '); return false">&laquo;</a>';
			for (var i = 1, stop_ = Math.ceil(this.zdjecia.length / this.naStronie); i <= stop_; i++)
			{
				html += ' ' + (i == strona ? i : '<a href="javascript:void(0)" onclick="' + this.id + '.wyswietl(' + i + '); return false" onkeypress="' + this.id + '.wyswietl(' + i + '); return false">' + i + '</a>');
			}
			if (strona < stop_) html += ' <a href="javascript:void(0)" onclick="' + this.id + '.wyswietl(' + (strona + 1) + '); return false" onkeypress="' + this.id + '.wyswietl(' + (strona + 1) + '); return false">&raquo;</a>';
			html += '</div>';
		}
		
		document.getElementById(this.id).innerHTML = '<div class="galeria">' + html + '</div>';
	}
	
	this._pokaz = function(i)
	{
		var numer = (i + 1) + '/' + this.zdjecia.length;
		if (this.zdjecia.length < 2) var stronicowanie = '';
		else
		{
			var stronicowanie =
				'<div class="stronicowanie" style="white-space: nowrap">' +
					(i > 0 ? '<a href="javascript:void(0)" onclick="setTimeout(\'document.write(window.opener.' + this.id + '._pokaz(' + (i - 1) + ')); document.close(); document.close()\', 1); return false" onkeypress="setTimeout(\'document.write(window.opener.' + this.id + '._pokaz(' + (i - 1) + ')); document.close(); document.close()\', 1); return false">&laquo;&nbsp;Wstecz</a>&nbsp;&nbsp;&nbsp;' : '') +
					numer +
					(i < this.zdjecia.length - 1 ? '&nbsp;&nbsp;&nbsp;<a href="javascript:void(0)" onclick="setTimeout(\'document.write(window.opener.' + this.id + '._pokaz(' + (i + 1) + ')); document.close()\', 1); return false" onkeypress="setTimeout(\'document.write(window.opener.' + this.id + '._pokaz(' + (i + 1) + ')); document.close()\', 1); return false">Dalej&nbsp;&raquo;</a>' : '') +
				'</div>';
		}
		
		var html =
			'<html>' +
				'<head>' +
					'<title>' + (typeof this.zdjecia[i][2] != 'undefined' ? this.zdjecia[i][2].replace(/<[^>]+>/g, '') + (numer ? ' (' + numer + ')' : '') : numer) + '</title>' +
					(typeof this.css != 'undefined' && this.css ? '<link rel="Stylesheet" type="text/css" href="' + this.css + '" />' : '') +
					'<'+'script type="text/javascript">' +
					'function dopasuj() { window.resizeTo(Math.min(screen.availWidth, Math.max(document.getElementById(\'img\').width + 50, document.getElementById(\'body\').offsetWidth)), Math.min(screen.availHeight, document.getElementById(\'body\').offsetHeight + 80)); }' +
					(this.ochrona ? 'window.onblur = function() { if (document.getElementById(\'body\')) document.getElementById(\'body\').style.visibility = \'hidden\'; try { clipboardData.clearData(); } catch (e) {} }; window.onfocus = function () { if (document.getElementById(\'body\')) document.getElementById(\'body\').style.visibility = \'visible\'; };'  : '') +
					'<'+'/script>' +
				'</head>' +
				'<body style="margin: 0; padding: 0" onload="dopasuj(); dopasuj()"' + (this.ochrona ? ' oncontextmenu="return false" onbeforeprint="document.getElementsByTagName(\'body\')[0].style.visibility = \'hidden\'; window.alert(\'Wydruk jest niedostępny!\')" onafterprint="document.getElementsByTagName(\'body\')[0].style.visibility = \'visible\'"' : '') + '>' +
					'<div id="body">' +
						'<div id="zdjecie">' +
							(typeof this.zdjecia[i][2] != 'undefined' || numer ? '<h1>' + (typeof this.zdjecia[i][2] != 'undefined' ? this.zdjecia[i][2] : numer) + '</h1>' : '') +
							'<div style="text-align: center"><img id="img" src="' + this.zdjecia[i][1] + '" alt=""' + (this.ochrona ? ' onmousedown="return false" oncontextmenu="return false" onselectstart="return false" onselect="return false" oncopy="return false" ondragstart="return false" ondrag="return false" galleryimg="no"' : '') + ' /></div>' +
							(typeof this.zdjecia[i][3] != 'undefined' ? '<div>' + this.zdjecia[i][3] + '</div>' : '') +
							stronicowanie +
						'</div>' +
					'</div>' +
				'</body>' +
			'</html>';
		
		return html;
	}
	
	this.pokaz = function(i)
	{
		try { Galeria.okno.close() } catch (e) {}
		Galeria.okno = window.open('', this.id, 'menubar=no,toolbar=no,location=no,directories=no,status=no,scrollbars=yes,resizable=yes,width=400,height=400');
		if (!Galeria.okno) return false;
		
		Galeria.okno.document.close();
		Galeria.okno.document.write(this._pokaz(i));
		Galeria.okno.document.close();
		Galeria.okno.focus();
		
		return true;
	}
	
	document.write('<div id="' + this.id + '"></div>');
	this.wyswietl();
}

Galeria.okno = null;

Na samym początku w wyróżnionych miejscach można zmienić podstawowe ustawienia konfiguracyjne: ilość kolumn, w których będą wyświetlane miniatury oraz ilość obrazków miniatur umieszczanych na jednej stronie.

Następnie na stronie, gdzie ma być umieszczona galeria, należy w nagłówku dokumentu (wewnątrz <head>...</head>) wstawić:

<script type="text/javascript" src="galeria.js"></script>

W wyróżnionym miejscu oczywiście należy podać lokalizację utworzonego wcześniej pliku galeria.js. Teraz wystarczy wkleić na stronie w wybranym miejscu przykładowy kod:

<script type="text/javascript">
// <![CDATA[
var galeria = new Galeria('galeria', new Array(
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis')
));
// ]]>
</script>
miniatura
Lokalizacja miniatury zdjęcia
zdjęcie
Lokalizacja pełnowymiarowego zdjęcia
Tytuł
Tytuł zdjęcia/podpis miniatury (opcjonalnie)
Opis
Szerszy opis zdjęcia (opcjonalnie)

UWAGA!
Zwróć uwagę, że po każdym elemencie, wprowadzającym do galerii kolejne zdjęcie ("miniatura, zdjęcie, Tytuł, Opis"), oprócz ostatniego musi być postawiony przecinek. Pominięcie przecinka lub postawienie go po ostatnim elemencie spowoduje błędy w skrypcie i galeria wcale się nie wyświetli!

Jak w każdym skrypcie JavaScript, w wartościach zmiennych ujętych w apostrofy (tutaj jest to Tytuł i Opis) nie wolno już używać apostrofów ("'") ani odwróconych ukośników ("\"). Jeżeli musimy ich użyć, należy poprzedzić je dodatkowym znakiem "\" - np. "\'", "\\". Poza tym wartości tych zmiennych muszą się znajdować w jednej linijce, tzn. absolutnie niedozwolone jest przełamywanie wiersza klawiszem Enter.

Zwróć również uwagę na wyróżnione wyrazy galeria: muszą być one w obu miejscach dokładnie identyczne, a dodatkowo nie mogą zawierać znaków zabronionych w identyfikatorach, tj. innych niż angielskie litery, cyfry (ale nie na początku) i podkreślniki ("_").
Aby umieścić w jednym dokumencie kilka oddzielnych galerii, należy powtórzyć tylko powyższą część kodu, modyfikując w nim właśnie wyróżniony identyfikator galeria - inny dla każdej galerii.

Ostatnie dwa parametry są nieobowiązkowe, tzn. można je pominąć:

new Array('miniatura', 'zdjęcie')
new Array('miniatura', 'zdjęcie', 'Tytuł')
new Array('miniatura', 'zdjęcie', '', 'Opis')

W opisie można bez przeszkód używać znaczników HTML, np. aby wprowadzić formatowanie tekstu lub podzielić treść na akapity.

Ponadto aby odpowiednio wystylizować galerię, można do niej dołączyć np. taki arkusz CSS:

.galeria {
	text-align: center;
}

.galeria table {
	margin-left: auto;
	margin-right: auto;
}

.galeria td {
	padding: 5px 5px 10px 5px;
}

.galeria td img {
	border: 1px solid black;
}

Najwygodniej będzie zapisać go w osobnym pliku z rozszerzeniem *.css - np. galeria_zdjec.css i osadzić w nagłówku dokumentu za pomocą znacznika:

<link rel="Stylesheet" type="text/css" href="galeria_zdjec.css" />

Oczywiście można go również dołączyć do już istniejącego arkusza stylów serwisu.

Wygląd strony z podglądem

Jak można zaobserwować, domyślny wygląd strony otwieranej w nowym oknie z podglądem pełnowymiarowego zdjęcia nie jest zbyt estetyczny. Aby to zmienić, należy przygotować osobny zewnętrzny arkusz stylów i zapisać go w pliku z rozszerzeniem *.css - np. galeria.css. Przykładowo:

body {
	font-size: 12px;
	font-family: Arial, Helvetica, sans-serif;
}

.zdjecie {
	padding: 10px;
	text-align: justify;
}

h1 {
	text-align: center;
	font-size: 20px;
	margin: 0;
	padding-bottom: 10px;
}

#img {
	margin-bottom: 10px;
}

.stronicowanie {
	text-align: center;
	margin-top: 1em;
	font-weight: bold;
}
.stronicowanie a:link, .stronicowanie a:visited {
	color: blue;
	text-decoration: none;
}
.stronicowanie a:hover {
	color: red;
}

Następnie lokalizację tego arkusza CSS należy podać przy tworzeniu galerii:

<script type="text/javascript">
// <![CDATA[
var galeria = new Galeria('galeria', new Array(
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis')
), 'galeria.css');
// ]]>
</script>

Ochrona przed kopiowaniem

Nie każdy pragnie udostępniać swoje zdjęcia w takiej formie, aby internauci mogli sobie je kopiować na swój dysk lokalny. Czasami zachodzi potrzeba jedynie prezentacji grafik, bez możliwości ich zapisu. Aby to zrobić, należy się posłużyć następującym kodem:

<script type="text/javascript">
// <![CDATA[
var galeria = new Galeria('galeria', new Array(
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis')
), 'galeria.css', true);
// ]]>
</script>

Nie ma stuprocentowego sposobu zablokowania kopiowania zdjęć ze stron WWW. Przedstawiona tutaj metoda stanowi tylko pewne utrudnienie dla osób początkujących.

Przeładowanie miniatur

Używając tego skryptu można zauważyć pewien efekt, który czasami może być niepożądany. Kiedy przechodzimy na kolejną stronę galerii, obrazki miniatur dopiero wtedy się doczytują. Aby załadować na zapas wszystkie miniatury jednocześnie, należy użyć kodu:

<script type="text/javascript">
// <![CDATA[
var galeria = new Galeria('galeria', new Array(
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis'),
	new Array('miniatura', 'zdjęcie', 'Tytuł', 'Opis')
), 'galeria.css', false, true);
// ]]>
</script>

Przeładowywane są tylko miniatury, a nie pełnowymiarowe zdjęcia.

Radzę stosować BARDZO rozważnie tą metodę! W przypadku obszernych galerii ładowanie strony może potrwać potwornie długo, a przecież użytkownik może wcale nie chcieć potem obejrzeć wszystkich zdjęć.

Przykład

Kliknij miniatury, aby zobaczyć podgląd pełnowymiarowego zdjęcia. Na końcu galerii znajduje się menu nawigacyjne, umożliwiające przejście na następną stronę.