Příkladová stránka widgetu LightBox

Konfigurace LightBoxu

Jak jsme si ukázali na předchozí stránce, LightBox je jednoduše nasaditelný. Při bližsím pohledu zjistíme, že při vytváření instance požaduje konstruktor dva parametry. Prvním je pole s informacemi o zobrazovaných obrázcích a druhým je konfigurační objekt.

Pole obrázků je ve stejném formátu jako pro původní prohlížečku obrázků, tedy:

 var data = [
 	{alt: 'Západ slunce', small: {url: '/img/gallery/tn01.jpg'}, big: {url: '/img/gallery/01.jpg'} },
 	{alt: 'Praděd', small: {url: '/img/gallery/tn02.jpg'}, big: {url: '/img/gallery/02.jpg'} },
 	{alt: 'Klaustrofobie', small: {url: '/img/gallery/tn03.jpg'}, big: {url: '/img/gallery/03.jpg'} },
 	{alt: 'Přehlídka armády', small: {url: '/img/gallery/tn04.jpg'}, big: {url: '/img/gallery/04.jpg'} }
 ];

Druhý konfigurační parametr je zcela jiný od původní prohlížečky obrázků a navíc poskytuje mnohem širší konfigurační možnosti. Zde je vhodné nastínit základní principy nového LightBoxu. LightBox jako takový je složen z komponent, které je možné konfigurovat samostatně a také je možné je nahradit jinou, požadovanou funkčností. V souboru s LightBoxem je definováno několik základních komponent, které lze libovolně zaměnit, nicméně je možné použít naprosto nové komponenty, které rozšiřují funkčnost LighBoxu, aniž by bylo nutné vlastní třídu LightBoxu upravovat.

Komponentní struktura LightBoxu

LightBox se skládá ze 7 základních komponent:

Tyto komponenty jsou v LightBoxu povinné a i když nejsou definované v konfiguraci, jsou použité výchozí komponenty. Některé komponenty jsou v základní verzi LighBoxu ve více verzích a je možné je v konfiguraci měnit, možné základní hodnoty jsou:

Použítí těchto komponent je následovné:

 var opt = {
 		components: {
 			strip: JAK.LightBox.Strip.Scrollable,
 			navigation: JAK.LightBox.Navigation.Basic,
 			anchorage: JAK.LightBox.Anchorage.Fixed,
 			main: JAK.LightBox.Main.CenteredScaled
 		}
 	};

 	var g = new JAK.LightBox(data, opt);

Takto definovaný LightBox bude mít pás s náhledovými obrázky, zobrazenou navigaci, její pozice bude vždy ve středu okna prohlížeče a hlavní obrázek bude centrován a zmenšen do svého prostoru. Pro nenadefinované komponenty se použijí výchozí hodnoty. Otázkou zůstává jak definovat rozměry tohoto prostoru a vlastně vzhled LightBoxu.

Vzhled a rozměry LightBoxu

Vzhled a rozměry Lightboxu a vyrenderování komponent jsou čistě popsány pomocí CSS. LightBox tyto rozměry při svém zobrazení přečte a komponenty díky tomu mohou galerii např. vycentrovat, nebo zmenšit do daného prostoru hlavní obrázek.

Každá komponenta má výchozí nastavení názvu třídy obalujícího prvku. V konfiguraci je možné tuto třídu předdefinovat, nebo nadefinovat id daného prvku. Třídu i id lze přiřadit i celému Lightboxu:

 var opt = {
 	galleryId: 'lightBox',
 	galleryClassName: 'lightboxclass',
	 components: {...
 	}
 };

Id použijeme pokud na stránce zobrazujeme pouze jednu galerii, pokud jich je více, použijeme třídu. Výchozí styl vypadá takto:

/*uzivatel musi mit na pameti ze chceme videt scrollbar vzdy, proto je nutne ho mit zapnuty a pocitat s jeho sirkou 17px!!!*/
/*tedy sirka galerie musi byt o 17px vice a sirka thmbus pole take, pokud je vse nalezato tak se jedna o vysku*/

/*rozmery galerie*/
#lightBox 							{background-color: black; width: 930px; height: 462px; padding-top:10px; padding-left: 10px; padding-right: 10px;}
#lightBox .image-browser-image					{width: 800px; height: 450px; border: 1px solid #333; overflow: hidden; padding: 0px; float: left; position: relative;}
/*nahledovy pas*/
#lightBox .image-browser-thumbs									{ width: 127px;height: 452px; overflow-y:scroll; float: right;}
#lightBox .image-browser-thumbs div.image-browser-thumb-box		{ height: 55px; width: 100px; padding: 0px; margin: 3px; border: 1px solid #333;}
#lightBox .image-browser-thumbs div.image-browser-active		{border: 3px solid red;}
/*ramecek okolo aktivniho nahledu*/
#lightBox .image-browser-active					{border: 3px solid red;}

/*zasednuti pod galerii*/
div.image-browser-root 					{ _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/bg.png', sizingMethod='scale' );}
div[class~="image-browser-root"] 			{ background: url(/img/widgets/lightbox/bg.png); }

/*ovladaci tlacitka*/
.image-browser-prev 					{ position: absolute; top: 20px; left: 20px; display: block; width: 42px; height: 36px; cursor: pointer; background: url(/img/widgets/lightbox/lb-previous-active.png); _background: none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-previous-active.png'));}
.image-browser-prev:hover				{ background: url(/img/widgets/lightbox/lb-previous-hover.png); _background: none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-previous-hover.png')); }
.image-browser-next 					{ position: absolute; top: 20px; left: 66px; display: block; width: 42px; height: 36px; cursor: pointer; background: url(/img/widgets/lightbox/lb-next-active.png); _background: none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-next-active.png')); }
.image-browser-next:hover				{ background: url(/img/widgets/lightbox/lb-next-hover.png); _background: none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-next-hover.png')); }
.image-browser-prev-disabled				{ position: absolute; top: 20px; left: 20px; display: block; width: 42px; height: 36px; cursor: pointer; background: url(/img/widgets/lightbox/lb-previous-inactive.png); _background: none;  _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-previous-inactive.png')); }
.image-browser-next-disabled				{ position: absolute; top: 20px; left: 66px; display: block; width: 42px; height: 36px; cursor: pointer; background: url(/img/widgets/lightbox/lb-next-inactive.png); _background: none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-next-inactive.png')); }
.image-browser-close					{ position: absolute; top: 20px; left: 760px; display: block; width: 42px; height: 36px; cursor: pointer; background: url(/img/widgets/lightbox/lb-close-active.png); _background:none ;_filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-close-active.png'));}
.image-browser-close:hover				{ background: url(/img/widgets/lightbox/lb-close-hover.png); _background:none; _filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/img/widgets/lightbox/lb-close-hover.png'));}

LightBox má rozměry 930 × 462px, a box (výchozí třída imge-browser-image) pro hlavní fotku má velikost 800 × 450px. Dále je zde nastylován pás náhledů (výchozí třída image-browser-thumbs), kde vidíme, že box pro jeden náhledový obrázek má 100 × 55px. Dále je definován rámeček okolo aktuálního náhledu (výchozí třída image-browser-active), který má 3px široký červený okraj. Zašedávač pod galeríí (výchozí třída image-browser-root) je tvořen jedním poloprůhledným obrázkem. Na konci stylopisu je blok stylů pro obrázky v navigaci. Předchozí a další mají stavy tři: neaktivní, aktivní a zvýrazněný při najetí myši. Zavírací tlačítko má stavz aktivní a zvýrazněný. LightBox generuje navíc skryté DIVy s id a className odvozenymi od id/class ovládacích prvků aby bylo možné provést preload obrázků použítých pro hover efekt. Pak je možné ještě nastylovat:

/*image preload pro hover obrazky navigace do poskytnutych skrytych DIVu, je mozno nacist i pro disabled */
div.image-browser-prev-preload			{ background: url(img/widgets/lightbox/lb-previous-hover.png);}
div.image-browser-next-preload			{ background: url(img/widgets/lightbox/lb-next-hover.png);}
div.image-browser-close-preload			{ background: url(img/widgets/lightbox/lb-close-hover.png);}

Galerii je možné otevřít odkazem: otevřít galerii. Pokud chceme zobrazovat popisky k obrázkům, zvolíme si správnou verzi komponenty description

 var opt = {
 	...
 	 components: {
 		...
 		description: JAK.LightBox.Description.Basic,
		 ...
 	},
 	...
 };

k datům přidáme vlastnost description

var data = [
 	{alt: 'Les pod sněhem',description: 'Les pod sněhem', small: {url: '/img/lightbox/tn_01.jpg'}, big: {url: '/img/lightbox/01.jpg'} },
 	{alt: 'Osvětim',description: 'Osvětim', small: {url: '/img/lightbox/tn_02.jpg'}, big: {url: '/img/lightbox/02.jpg'} },
 	{alt: 'MIG-15 ve vojenském muzeu Kbely',description: 'MIG-15 ve vojenském muzeu Kbely', small: {url: '/img/lightbox/tn_03.jpg'}, big: {url: '/img/lightbox/03.jpg'} },
 	{alt: 'Rozhledna',description: 'Rozhledna', small: {url: '/img/lightbox/tn_04.jpg'}, big: {url: '/img/lightbox/04.jpg'} },
 	{alt: 'Beruška',description: 'Beruška', small: {url: '/img/lightbox/tn_05.jpg'}, big: {url: '/img/lightbox/05.jpg'} },
 	{alt: 'Česká kotlina',description: 'Česká kotlina', small: {url: '/img/lightbox/tn_06.jpg'}, big: {url: '/img/lightbox/06.jpg'} },
 	{alt: 'Mochomůrka červená - houba nejedlá',description: 'Mochomůrka červená - houba nejedlá', small: {url: '/img/lightbox/tn_07.jpg'}, big: {url: '/img/lightbox/07.jpg'} },
 	{alt: 'Surikata - nejfotogeničtější zvířátko v ZOO',description: 'Surikata - nejfotogeničtější zvířátko v ZOO', small: {url: '/img/lightbox/tn_08.jpg'}, big: {url: '/img/lightbox/08.jpg'} }
 ];

a nastavíme vzhled, tak aby se zobrazovala pod hlavním obrázkem

 /*styly pro popisku*/
 #lightBox .image-browser-caption	{ height: 50px; width: 800px; float: left; padding-left:5px; color: #999; padding-top: 7px; font-family:Arial, Helvetica, sans-serif; line-height:140%; font-size: 12px; /*napevno protoze je to v tabulce*/}

Galerie s popiskem je zobrazitelná tímto odkazem.

Základní možnosti nastavení LightBoxu

Jak jsme si již ukázali v konfiguračním objektu LightBoxu (druhý parametr konstruktoru) je definice jednotlivých komponent galerie a také jsme si ukázali definici id a třídy. Tento objekt obsahuje další konfigurační vlastnosti a to:

 var opt = {
 	galleryClassName: "lightBox2",
 	zIndex: 10,
 	useShadow: true,
 	imagePath: '/img/widgets/lightbox/shadow-',
 	usePageShader: false,
 	components: {
 			strip: JAK.LightBox.Strip.Scrollable,
 			navigation: JAK.LightBox.Navigation.Basic,
 			anchorage: JAK.LightBox.Anchorage.Fixed,
 			main: JAK.LightBox.Main.CenteredScaled,
 			description: JAK.LightBox.Description.Basic
 	}
 };

 var g3 = new JAK.LightBox(data, opt);

Oproti původní galerii se změnily hlavně velikosti stínů, protože nový LightBox dostal nové stíny a zakulacené rohy. Ukázka je zde.

Další část konfigurace se týká jednotlivých komponent. Každá komponenta má vlastní konfigurační objekt uložený ve vlastnosti s názvem: <název komponenty>Opt. Jednotlivé komponenty, které obsahuje LightBox mají toto nastavení:

Pokročile nastavený LightBox s nekontinuální navigací, zašedlými tlačítky předchozí / další na první a poslední fotce, rámeček kolem aktivního náhledu zvenčí a přechodem mezi obrázky:

 var opt = {
 	galleryClassName: "lightBox2",
 	zIndex: 10,
 	useShadow: true,
 	imagePath: '/img/widgets/lightbox/shadow-',
 	usePageShader: false,
 	components: {
 		strip: JAK.LightBox.Strip.Scrollable,
 		navigation: JAK.LightBox.Navigation.Basic,
 		anchorage: JAK.LightBox.Anchorage.Fixed,
 		main: JAK.LightBox.Main.CenteredScaled,
 		description: JAK.LightBox.Description.Basic,
 		transition: JAK.LightBox.Transition.Fade
 	},
 	stripOpt : {
 		activeBorder : 'outer'
 	},
 	navigationOpt : {
 		continuous: false,
 		showDisabled: true
 	},
 	transitionOpt: {
 		interval: 500,
 		overlap: 0.5
 	}
 };

 var g4 = new JAK.LightBox(data, opt);

Zobrazení galerie.

Použití prolínačky pro přechod mezi obrázky vyžaduje přilinkování interpolátoru a metronomu. Interpolátor je možné stáhnout přímým odkazem zde: interpolators.zip (obsahuje i metronom).

Horizontální náhledový pás

V následující ukázce stylů a konfigurace je LightBox nastylován tak, aby náhledový pás byl pod hlavním obrázkem. Jediné co musíme nastavit je, že strip má být renderován horizonálně:

var optH = {
 	galleryClassName: "lightBox3",
 	zIndex: 10,
 	components: {
  		strip: JAK.LightBox.Strip.Scrollable,
  		navigation: JAK.LightBox.Navigation.Basic,
  		anchorage: JAK.LightBox.Anchorage.Fixed,
  		main: JAK.LightBox.Main.CenteredScaled,
  		description: JAK.LightBox.Description.Basic
 	},
 	stripOpt: {
 		orientation: 'horizontal',
 		activeBorder: 'outer'
 	}
 };

Dále je nutné přepočítat styly, takže hlavně měníme pozicování stripu a rozměry LightBoxu:

/*galerie s obrazky dole*/

 .lightBox3 				{background-color: black; width: 800px; height: 547px; padding-top:10px; padding-left: 10px; padding-right: 10px;}
 .lightBox3 .image-browser-image	{width: 800px; height: 450px; border: 1px solid #333; overflow: hidden; padding: 0px; float: left; position: relative;}
 /*nahledovy pas*/
 .lightBox3 .image-browser-thumbs	{ width: 800px;height: 81px; overflow-x:scroll; clear: both;}
 .lightBox3 .image-browser-thumbs div.image-browser-thumb-box		{ height: 55px; width: 100px; padding: 0px; margin: 3px; border: 1px solid #333;}
 /*ramecek okolo aktivniho nahledu*/
 .lightBox3 .image-browser-thumbs div.image-browser-active		{border: 3px solid red;}
 /*styly pro popisku*/
 .lightBox3 .image-browser-caption	{ display: none;}

Zobrazení galerie.

Programové rozhranní LightBoxu

Pokud máme vybrané komponenty, nastavené jejich parametry a definované CSS, chceme mít možnost LightBox programově ovládat. LightBox jednak poskytuje veřejné metody, kterými je možné navěsit na odkazy jeho otevření, a také poskytuje metody na jeho otevření, uzavření, nebo přechod na konkrétní obrázek.

Mějme náhledové obrázky v DIVu s id gallery1:

pak pomocí metody bindAnchors na tyto obrázky navěsíme posluchače na click událost. Po kliknutí se LighBox otevře na obrázků s pořadovým číslem shodným s pořadím obrázku na který bylo kliknuto.

 var g5 = new JAK.LightBox(data, opt);
 g5.bindAnchors('gallery1');

LightBox má dále metodu bindElement, která je volnější než, bindAnchors, tedy na předaný element navěsí click událost a druhým parametrem se předá pořadí obrázku, na kterém se má LightBox otevřít. Vytvoříme si tlačítka, která otevřou mapu na 2., 4. a 6. obrázku.

<script type="text/javascript">
 var g6 = new JAK.LightBox(data, opt);
</script>

<input type="button" value="2" onclick="g6.show(1); return false;" />
<input type="button" value="4" onclick="g6.show(3); return false;" />
<input type="button" value="6" onclick="g6.show(5); return false;" />

Otevři obrázek: . Je vhodné si všimnout, že číslování pořadí obrázků v LightBoxu je od nuly, tudíž, první obrázek má index 0, druhý 1, atd.

LightBox má dále tyto metody:

Poslední zajímavou metodou, je statická metoda JAK.LightBox.create. Pokud máme na stránce blok s odkazy na velké fotorafie a v odkazu je náhled, můžeme tento blok předat jako parametr této metodě a ta vytvoří instanci LightBoxu bez nutnosti JS objektu s daty o obrázcích.

<div id="gallery2">
	<a href="/img/lightbox/01.jpg"><img src="/img/lightbox/tn_01.jpg" alt="Les pod sněhem" /></a>
	<a href="/img/lightbox/02.jpg"><img src="/img/lightbox/tn_02.jpg" alt="Osvětim" /></a>
	<a href="/img/lightbox/03.jpg"><img src="/img/lightbox/tn_03.jpg" alt="MIG-15 ve vojenském muzeu Kbely" /></a>
	<a href="/img/lightbox/04.jpg"><img src="/img/lightbox/tn_04.jpg" alt="Rozhledna" /></a>
	<a href="/img/lightbox/05.jpg"><img src="/img/lightbox/tn_05.jpg" alt="Beruška" /></a>
	<a href="/img/lightbox/06.jpg"><img src="/img/lightbox/tn_06.jpg" alt="Česká kotlina" /></a>
	<a href="/img/lightbox/07.jpg"><img src="/img/lightbox/tn_07.jpg" alt="Mochomůrka červená - houba nejedlá" /></a>
	<a href="/img/lightbox/08.jpg"><img src="/img/lightbox/tn_08.jpg" alt="Surikata - nejfotogeničtější zvířátko v ZOO" /></a>
</div>
<script type="text/javascript">
 var g7 = JAK.LightBox.create('gallery2', opt);
</script>
Les pod sněhem Osvětim MIG-15 ve vojenském muzeu Kbely Rozhledna Beruška Česká kotlina Mochomůrka červená - houba nejedlá Surikata - nejfotogeničtější zvířátko v ZOO

Vysílané signály LightBoxem

Pokud bychom chtěli reagovat na nastalé události v LightBoxu, můžeme naslouchat na tyto události:

LightBox obsahuje také veřejnou metodu createEvent, kterou využívají komponenty pro vyvolání událostí, které vznikly v komponentě, ale chceme je propagovat pro všechny posluchače LightBoxu. Tuto metodu používají v současné době dvě komponenty:

Vytvoření nového pluginu

LightBox je výjimečný tím, že je možné ho velice jednoduše rozšiřovat o další funkčnost. Buď tím, že podědíme z jedné z výchozích komponent a upravíme její funkčnost, nebo si můžeme vytvořit komponentu vlastní, která rozšiřuje LightBox o chování, které je specifické pro dané použití.

Pozicování galerie na střed okna se zachováním viditelnosti ovládacích prvků

Pokud využijeme pozicování na střed, pomocí komponenty JAK.LightBox.Anchorage.Fixed, a zároveň prohlížíme velké obrázky na malém displayi, může se lehce stát, že ovládací prvky LightBoxu budou nedostupné, zobrazené mimo průzor. Proto si ukážeme napsání nového pozicovače, který bude pozicovat LightBox na střed, ale pokud bude průzor malý, bude ho pozicovat tak, aby byly ovládací prvky viditelné.

/**
 * Pozicovani na stred s moznosti vzdy videt ovladaci prvky
 **/
JAK.LightBox.Anchorage.Fixed.WithNavigation = JAK.ClassMaker.makeClass({
	NAME: 'JAK.LightBox.Anchorage.Fixed.WithNavigation',
	EXTEND: JAK.LightBox.Anchorage.Fixed,
	VERSION: '1.0',
	CLASS: 'class'
});

JAK.LightBox.Anchorage.Fixed.WithNavigation.prototype.$constructor = function(owner) {
	this.$super(owner);

	/**
	 * nacteni z konfigurace dodatecnych informaci, defaultni odsazeni pokud je galerie vetsi nez pruhled
	 */
	this.options.topOffset = owner.options.anchorageOpt.topOffset || 3;
	this.options.leftOffset = owner.options.anchorageOpt.leftOffset || 3;
};

 /**
  * metoda je volana defaultne pri zobrazeni galerie aby se galerie napozicovala
  */
 JAK.LightBox.Anchorage.Fixed.WithNavigation.prototype._position = function() {
 	var portSize = JAK.DOM.getDocSize();
 	var containerWidth = parseInt(JAK.DOM.getStyle(this.container, 'width'));
 	var containerHeight = parseInt(JAK.DOM.getStyle(this.container, 'height'));

 	/**
 	 * ti co neumi position fixed pozicuji pres absolute
 	 */
 	if (this.useAbsoluteHack) {
 		var wScroll = JAK.DOM.getScrollPos();
 		this.container.style.position = 'absolute';

 		if (portSize.height < containerHeight) {
 			this.container.style.top = Math.round(wScroll.y + this.options.topOffset)+'px';
 		} else {
 			this.container.style.top = Math.round(wScroll.y + portSize.height/2 - this.container.offsetHeight/2)+'px';
 		}

 		if (portSize.width < containerWidth) {
 			this.container.style.left = Math.round(wScroll.x + this.options.leftOffset)+'px';
 		} else {
 			this.container.style.left = Math.round(wScroll.x + portSize.width/2 - this.container.offsetWidth/2)+'px';
 		}

 	/**
 	 * absolutni pozicovani
 	 */
 	} else {
 		this.container.style.position = 'fixed';

 		if (portSize.height < containerHeight) {
 			this.container.style.top = this.options.topOffset+'px';
 		} else {
 			this.container.style.top = Math.round(portSize.height/2 - this.container.offsetHeight/2)+'px';
 		}

 		if (portSize.width < containerWidth) {
 			this.container.style.left = this.options.offsetWidth+'px';
 		} else {
 			this.container.style.left = Math.round(portSize.width/2 - this.container.offsetWidth/2)+'px';
 		}
 	}
 };

 opt.components.anchorage = JAK.LightBox.Anchorage.Fixed.WithNavigation;
 var g7 = new JAK.LightBox(data, opt);

Z kódu výše je vidět, jak jsme podědili z ukotvení JAK.LightBox.Anchorage.Fixed a přepsali konstruktor, do kterého si můžeme předat volitelné parametry offsetTop a offsetLeft udávající odsazení LightBoxu, pokud se nevejde do průzoru. Dále jsme přepsali vnitřní metodu _position, která se od původní liší pouze testy na velikost okna ku velikosti LightBoxu. Zobrazení ukázkové galerie.

Vlastní komponenta zobrazující počet fotografií

Druhou možností rozšiřování LightBoxu je doplnění o novou funkčnost. V Novinkách zobrazujeme počet fotografií v galerii. Tuto funkcionalitu zajišťuje takováto komponenta:

 /*-------------pocet fotek---------------*/
 JAK.Photos = JAK.ClassMaker.makeClass({
 	NAME: 'JAK.Photos',
 	VERSION: '1.0',
 	CLASS: 'class',
 	IMPLEMENT: [JAK.ISignals]
 });

 /**
  * konstruktor
  */
 JAK.Photos.prototype.$constructor = function(owner) {
 	this.owner = owner;
 	this._render();
 };

 /**
  * privatni metoda starajici se o vyrenderovani komponenty
  */
 JAK.Photos.prototype._render = function() {
 	var c = JAK.cel('div', 'image-browser-photo-count');
 	var n = this.owner.data.length;
 	var text = n > 0 && n < 5 ? 'fotografie' :  'fotografií';
  	c.innerHTML = n+' '+text;
 	this.owner.dom.content.appendChild(c);
 };

Na začátku je třeba vědět, že o nové komponentě LightBoxu dáme vědět pomocí konfiguračního objektu. Do teď jsme používali zabudované komponenty a ty jsme definovali pomocí vlastnosti components. V této vlastnosti může být navíc vlastnost s název others, což je pole vlastních komponent. Je to pole objektů, které vyžaduje metoda JAK.Components::addNewComponent. Přidání do našeho konfiguračního objektu může vypadat takto:

 var opt = {
	...
 	components: {
 		strip: JAK.LightBox.Strip.Scrollable,
 		navigation: JAK.LightBox.Navigation.Basic,
 		anchorage: JAK.LightBox.Anchorage.Fixed,
 		main: JAK.LightBox.Main.CenteredScaled,
 		description: JAK.LightBox.Description.Basic,
 		transition: JAK.LightBox.Transition.Fade,
		others : [
				{name: 'photos', part: JAK.Photos}
			]
	 },
 	...
 };

Dále v našem kódu nastavujeme DIVu s počtem fotografií třídu image-browser-photo-count, abychom mohli tento box nastylovat:

 #lightBox .image-browser-photo-count	{ width: 100px; height: 50px; margin-right: 15px; padding-top: 7px; text-align: center; float: right; color: #999; font-family:Arial, Helvetica, sans-serif; line-height:140%; font-size: 12px;/*napevno protoze je to v tabulce*/ }

Při vytváření LightBoxu, jsou tyto ostatní komponenty renderovány ihned po vestavěných. Parametr předávaný do konstruktoru komponenty je reference na objekt LightBoxu, proto se můžeme v metodě _render odkazovat na this.owner.dom.content, což je DIV, do kterého se renderují všechny komponenty. Zobrazení galerie.

Životní cyklus komponent

Pokud podědíme některou z vestavěných komponent, je třeba vědět, kdy jsou vytvořeny, kdy se tvoří obsah a kdy se aktualizuje.

Vestavěné komponenty jsou inicializovány v konstruktoru LightBoxu, kdy jsou vytvořeny jejich instance. Poté je zavolána také jejich metoda render, která vrací DOM strukturu, kteoru LightBox připíná do svého obsahového okna.

Dále je vyslán signál renderDone. Poté jsou vytvořeny ostatní komponenty z pole others (viz výše). Těm není volána metoda render, protože nemusí být vizuální.

Při zobrazení LightBoxu a změně obrázku je volána u všech vestavěných komponent metoda actualizePosition. Ostatní komponenty pokud chtějí reagovat na stav LightBoxu musí naslouchat na příslušné signály.

Destruktor komponenty je volán při destrukci LightBoxu.

SlideShow

Pokud víme jak vytvořit jednoduchou rozširující komponentu a známe životní cyklus, můžeme se pustit do složitější komponenty, která bude umět spustit slideshow obrázků v Lightboxu.

Komponenta bude mít dvě tlačítka pro spuštění a zastavení SlideShow. Komponenta by měla mít možnost zvolit dobu po kterou je zobrazen jeden obrázek a také zda se po zobrazení LightBoxu automaticky slideshow spustí, či až na vyžádání. Také je vhodné mít možnost definovat id a CSS třídy pro jednotlivé prvky.

Konfiguraci do našeho objektu budeme předávat pomocí třetího parametru konstruktoru, který je u komponent vyhrazen pro konfigurační objekt.

 /*-----------------slideshow-----------------------*/
 JAK.SlideShow = JAK.ClassMaker.makeClass({
 	NAME: 'JAK.SlideShow',
 	VERSION: '1.0',
 	CLASS: 'class',
 	IMPLEMENT: [JAK.ISignals]
 });

 JAK.SlideShow.prototype.$constructor = function(owner, name, settings) {
 	this.owner = owner;
 	this.options = {
 		duration : 2,
 		autoplay: false,
 		id : false,
 		className: 'image-browser-slideshow',
 		pauseId: false,
 		pauseClassName: 'image-browser-slideshow-pause',
 		playId: false,
 		playClassName: 'image-browser-slideshow-play'
 	};
 	/*prepsani vychoziho nastaveni z uziv. konfigurace*/
	for (var p in settings) { this.options[p] = settings[p]; }
 	/*interval pro animaci*/
 	this.interval = null;
 	/*zbindovani metody pro pouziti v intervalu*/
 	this._timeoutDone = this._timeoutDone.bind(this);
 	/*uschovna DOM elementu*/
 	this.dom = {};

 	this._addEvents();
 	this._render();
 	/*schovani jednoho z tlacitek*/
 	this.options.autoplay ? this._hidePlay() : this._hidePause();
 };

 JAK.SlideShow.prototype.$destructor = function(){
 	this.removeListener('close', '_stop', this.owner);
 	this.removeListener('transitionDone', '_next', this.owner);

 	for (var i in this) {
 		this[i] = null;
 	}
 };

 JAK.SlideShow.prototype._addEvents = function() {
 	if (this.options.autoplay) {
 		this.addListener('transitionDone', '_next', this.owner);
 	}
 	this.addListener('close', '_stop', this.owner);
 };

 JAK.SlideShow.prototype._render = function() {
 	var c = JAK.cel('div', this.options.className, this.options.id);

 	var pause = JAK.cel('a', this.options.pauseClassName, this.options.pauseId);
 	pause.href = '#';
 	c.appendChild(pause);

 	var play = JAK.cel('a', this.options.playClassName, this.options.playId);
 	play.href = '#';
 	c.appendChild(play);

 	JAK.Events.addListener(pause, 'click', this, '_stopClick');
 	JAK.Events.addListener(play, 'click', this, '_playClick');

 	this.dom.pause = pause;
 	this.dom.play = play;

 	this.owner.dom.content.appendChild(c);
 };

 /**
  * metoda spustena pri kliku na tlacitko pause
  * @param {event} e
  * @param {HTMLelement} elm
  */
 JAK.SlideShow.prototype._stopClick = function(e, elm) {
 	JAK.Events.cancelDef(e);
 	this.removeListener('transitionDone', '_next', this.owner);
 	this._hidePause();
 	this._stop();
 };

 /**
  * metoda spustena pri kliku na tlacitko play
  * @param {event} e
  * @param {HTMLelement} elm
  */
 JAK.SlideShow.prototype._playClick = function(e, elm) {
 	JAK.Events.cancelDef(e);
 	this.addListener('transitionDone', '_next', this.owner);
 	this._hidePlay();
 	this._next();
 };

 /**
  * zastaveni slideshow
  */
 JAK.SlideShow.prototype._stop = function() {
 	clearTimeout(this.interval);
 };

 /**
  * spusteni slideshow
  */
 JAK.SlideShow.prototype._next = function() {
 	this.interval = setTimeout(this._timeoutDone, this.options.duration*1000);
 };

 /**
  * schovani tlacitka play, zobrazeni pause
  */
 JAK.SlideShow.prototype._hidePlay = function() {
 	this.dom.play.style.display = 'none';
 	this.dom.pause.style.display = '';
 };

 /**
  * schovani tlacitka pause, zobrazeni play
  */
 JAK.SlideShow.prototype._hidePause = function() {
 	this.dom.play.style.display = '';
 	this.dom.pause.style.display = 'none';
 };

 /**
  * metoda volana timeoutem, ktery je nastaven v metode _next
  * zde je vlastni posunuti na dalsi obrazek
  */
 JAK.SlideShow.prototype._timeoutDone = function() {
 	clearTimeout(this.interval);
 	this.owner.next();
 };

 /*-----------------------------*/
 

 opt.components.others.push({name: 'slideshow', part: JAK.SlideShow});
 var g9 = new JAK.LightBox(data, opt);

Ihned v konstruktoru voláme metodu _render, abychom vyrenderovali ovládací tlačítka. Dále navěsíme posluchače na signály LightBoxu close pro zastavení animace a transitionDone, pro start odpočtu zobrazení dalšího obrázku. Tento signál posloucháme od začátku, pouze pokud je vlastnost autoplay zapnutá.

Další metody jsou navěšeny na tlačítka a tedy ovládají timeout pro zobrazení dalšího obrázku. Zobrazení galerie

Předat parametry naší SlideShow můžeme pak takto:

var opt = {
 		components: {
 			strip: JAK.LightBox.Strip.Scrollable,
 			navigation: JAK.LightBox.Navigation.Basic,
 			anchorage: JAK.LightBox.Anchorage.Fixed,
 			main: JAK.LightBox.Main.CenteredScaled,
 			others: [
 				{name: 'slideshow', part: JAK.SlideShow, setting: {duration: 5, autoplay: true}}
			 ]
		 }
 	};

Renderování galerie a přístup k uživatelům se zrakovým postižením

Aby bylo možné galerie inicializovat a používat ihned, bez nutnosti čekat na načtení celé stránky, využívá Lightbox skrytého prvku, který je umístěn do tagu body na začátek, před veškerý obsah, pro vyrenderování svých částí. V průběhu načítání stránky nelze připínat na konec body, protože ještě není znám. Z toho vyplývá, že tento obsah, až je před normálními uživateli skryt, je viděn zrakově postiženými uživateli, pokud používají čtečky, které nedokáží rozeznat z CSS, že jsou prvky skryty.

Každý LightBox proto generuje neviditelné odkazy pro přeskočení obsahu galerie a obsahu všech galerií tak aby zrakově postižený nemuseli stále procházet obsah galerií i když nejsou zobrazeny. Pokud je galerie pojmenována vlastností galleryName, je tento název renderován do názvu galerie pro zrakově postižené, aby věděli, nejen jakou galerii přeskakují, ale i jaká galerie se jim zobrazila.

Pokud by nebylo vhodné výchozí chování LightBoxu, kdy je jeho kód pro budoucí použití renderován do elementu na začátku body, je možné toto chování změnit. Ve jmeném prostoru JAK.LightBox je statická vlastnost JAK.LightBox.container, do kterého můžeme uložit, před vytvárením instance LightBoxu, referenci na DOM element, do kterého se budou galerie vytvářet. Podmínkou je, že tento element je v době přiřazení znám.

Pokud vytvoření tohoto elementu nenecháte na LightBoxu, ale vytvoříte ho sami, je nutné vzít na sebe i zodpovědnost o jeho skrytí před zraky běžných uživatelů. Proto mu doporučujeme nastavit tyto styly:

 .container {
  	position:absolute;
 	left: -100px;
 	overflow: hidden;
 	width: 1px;
 	height: 1px;
 }
	
Požadované knihovny: Volitelné knihovny:

Knihovna interpolator.js je nutná pouze pokud chceme použít animace/prolínání při přechodech mezi jednotlivými prvky galerie.

Stáhnout widget lightbox.zip.