главная

Теги:


Создание галереи с предпросмотром миниатюр

В этом уроки я покажу вам как создать галерею на jQuery с возможностью предпросмотра миниатюр каждой фотографии. Идея заключается в том, чтобы при наведении курсора мыши на точки, появлялась миниатюра соответствующей фотографии в галерее. При нажатии на эту точку, с правой или левой стороны будет возникать оригинальная фотография.

В уроке будут использоваться фотографии geishaboy500, которые можно найти на его Flickr аккаунте.

Начнём же!

Разметка

HTML структура будет состоять из основного контейнера где будут появляться большие фотографии, а так же навигация по миниатюрам:

 
 

Просматриваемая миниатюра представляет собой элемент списка. Этому элементу мы дадим специальный класс т.к. хотим, чтобы он отличался от других. Каждый элемент в списке миниатюр содержит ссылку, которая содержит информацию и о самой миниатюре и о оригинальной фотографии. Используя JavaScript, мы будем динамически помещать оригинальное фото на нашу "сцену" путём извлечения пути из атрибута ссылки.

Теперь давайте посмотрим что у нас со стилями.

CSS

В первую очередь, оформим главный контейнер. В соответствии с максимальными размерами фото (680 на 450 пикселей), выставим контейнеру такие же параметры (оставив место для списка миниатюр):

 .ps_container{
	display:none;
	width:680px;
	height:500px;
	margin:20px auto 0px auto;
	position:relative;
}

Теперь мы оформим контейнер для больших фото. Тут мы установим максимальные размеры, а всё остальное скроем. Это нужно для того, чтобы фотографии анимационно менялись. В нашей JS функции мы как раз этим и займёмся.

Отцентрируем представление фотографий с помощью внешних отступов:

.ps_image_wrapper{
	width:680px;
	height:450px;
	overflow:hidden;
	position:relative;
	margin:0 auto;
	-moz-box-shadow:0px 0px 5px #999;
	-webkit-box-shadow:0px 0px 5px #999;
	box-shadow:0px 0px 5px #999;
}
 

Позиционируем фотографии абсолютно для возможности слайдинга:

.ps_image_wrapper img{
	position:absolute;
	left:0px;
	top:0px;
}
 

Элементы навигации будут оформлены следующим образом:

 .ps_prev,
.ps_next{
	width:30px;
	height:59px;
	position:absolute;
	top:50%;
	margin-top:-40px;
	cursor:pointer;
	opacity:0.5;
}
.ps_prev{
	background:transparent url(../images/prev.png) no-repeat top center;
	left:-50px;
}
.ps_next{
	background:transparent url(../images/next.png) no-repeat top center;
	right:-50px;
}
.ps_prev:hover,
.ps_next:hover{
	opacity:0.9;
}

Список с классом “ps_nav” будет располагаться под полными фотографиями и отцентрирован при помощи внешних отступов:

ul.ps_nav{
	list-style:none;
	margin:0;
	padding:0;
	width:170px;
	margin:20px auto;
	position:relative;
}
 

Ставим значение float для списка:

ul.ps_nav li{
	float:left;
}
 

Каждая ссылка на миниатюру представляет собой точку:

 ul.ps_nav li a{
	display:block;
	text-indent:-9000px;
	width:11px;
	height:11px;
	outline:none;
	padding:0px 3px;
	background:transparent url(../images/dot.png) no-repeat top center;
}

При наведении мы изменим позицию фона:

 ul.ps_nav li a:hover,ul.ps_nav li.selected a{
	background-position:50% -11px;
}

Специальный элемент, содержащий миниатюру будет позиционироваться абсолютно. Значение top отрицательно, т.к. мы хотим, чтоб элемент возникал над списком. Значение left будет вычисляться динамически. -34.5 пикселя это значение left для самой первой миниатюры в списке:

 ul.ps_nav li.ps_preview{
	display:none;
	width:85px;
	height:91px;
	top:-95px;
	left:-34.5px; /*Высчитывается динамически*/
	position:absolute;
}

Описываем стиль для маленького треугольника:

 ul.ps_nav li.ps_preview span{
	background:transparent url(../images/triangle.png) no-repeat top center;
	width:15px;
	height:6px;
	position:absolute;
	top:85px;
	left:35px;
}

Представление миниатюры будет точно такое же как и у фото. Всё остальное мы скроем:

.ps_preview_wrapper{
	width:75px;
	height:75px;
	border:5px solid #fff;
	overflow:hidden;
	position:relative;
	-moz-box-shadow:0px 0px 5px #999;
	-webkit-box-shadow:0px 0px 5px #999;
	box-shadow:0px 0px 5px #999;
}
 

В итоге мы хотим, чтобы миниатюры позиционировались абсолютно т.к. мы хотим добиться анимированного эффекта слайдера:

.ps_preview_wrapper img{
	position:absolute;
	top:0px;
	left:0px;
}
 

Со стилями покончено. Настало время добавить jQuery!

JavaScript

Главная идея этой галереи показывать пользователю миниатюры фотографий когда он проводит мышкой по точкам представляющими собой изображения.

Когда курсор мыши будет проходится по точкам мы хотим добиться эффекта слайдера между миниатюрами. Это довольно таки эффектно смотрится.

При клике мы так же будем анимировано менять изображение учитывая какое фото показывать в дальнейшем (справа или слева).

Такого эффекта мы можем добиться, поместив все фото рядом и анимируя значение left каждого изображения.

Давай те же начнём:

var $ps_container = $('#ps_container'),
	$ps_image_wrapper = $ps_container.find('.ps_image_wrapper'),
	$ps_next = $ps_container.find('.ps_next'),
	$ps_prev = $ps_container.find('.ps_prev'),
	$ps_nav = $ps_container.find('.ps_nav'),
	$tooltip = $ps_container.find('.ps_preview'),
	$ps_preview_wrapper = $tooltip.find('.ps_preview_wrapper'),
	$links = $ps_nav.children('li').not($tooltip),
	total_images = $links.length,
	currentHovered = -1,
	current = 0,
	$loader = $('#loader');
 

(Элемент загрузки не был упомянут в HTML структуре т.к. он находится за пределами главного контейнера. Мы будем показывать элемент загрузки до тех пор, пока все фото не загрузятся)

Теперь проверим что у нас за браузер:

var ie = false;
if ($.browser.msie) {
	ie = true; // о нет!
}
if(!ie) // то Бог существует
	$tooltip.css({
		opacity	: 0
	}).show();
 

Мы хотим чтобы у миниатюры значение opacity было равно 0 по умолчанию и 1 когда мы наводим на неё мышкой. Т.к. в IE возникают проблемы с фильтром opacity мы будем использовать show/hide вместо анимирования opacity. Так же мы добавляем display:none если браузер IE.

После загрузки изображений, покажем страницу:

/*для начала загрузим изображение (миниатюру и полное)*/
var loaded	= 0;
$links.each(function(i){
	var $link 	= $(this);
	$link.find('a').preload({
		onComplete	: function(){
			++loaded;
			if(loaded == total_images){
				//когда все изображения загрузились,
				//показываем ps_container и инициализируем события
				$loader.hide();
				$ps_container.show();
				//как только мышка проходит по точкам,
				//показываем tooltip,
				//и когда мышка не находится над точкой, убираем tooltip
				//а если произошёл клик, показываем соответствующее фото
				$links.bind('mouseenter',showTooltip)
					  .bind('mouseleave',hideTooltip)
					  .bind('click',showImage);
				//навигация по фотографиям
				$ps_next.bind('click',nextImage);
				$ps_prev.bind('click',prevImage);
			}
		}
	});
});
 

Функция showTooltip() показывает миниатюру и отвечает за анимацию оттуда, “откуда мы пришли”:

function showTooltip(){
	var $link = $(this),
		idx	= $link.index(),
		linkOuterWidth	= $link.outerWidth(),
		//значение для left
		left = parseFloat(idx * linkOuterWidth) - $tooltip.width()/2 + linkOuterWidth/2,
		//источник миниатюры
		$thumb = $link.find('a').attr('rel'), imageLeft;

	//если мы навели мышку не на текущий элемент
	if(currentHovered != idx){
		//check if we will animate left->right or right->left
		if(currentHovered != -1){
			if(currentHovered < idx){
				imageLeft	= 75;
			}
			else{
				imageLeft	= -75;
			}
		}
		currentHovered = idx;

		//вычисляем следующую миниатюру
		var $newImage = $('').css('left','0px').attr('src',$thumb);

		//если больше чем 1 изображение
		//(это может случиться если быстро провести мышкой)
		//удаляем старое (:last)
		if($ps_preview_wrapper.children().length > 1)
			$ps_preview_wrapper.children(':last').remove();

		//прикрепляем новое изображение
		$ps_preview_wrapper.prepend($newImage);

		var $tooltip_imgs = $ps_preview_wrapper.children(),
			tooltip_imgs_count = $tooltip_imgs.length;

		//если на tooltip 2 изображения
		//то одно прячем, другое показываем
		if(tooltip_imgs_count > 1){
			$tooltip_imgs.eq(tooltip_imgs_count-1)
				 .stop()
				 .animate({
					left:-imageLeft+'px'
				  },150,function(){
						//remove the old one
						$(this).remove();
				  });
			$tooltip_imgs.eq(0)
				 .css('left',imageLeft + 'px')
				 .stop()
				 .animate({
					left:'0px'
				},150);
		}
	}
	//если мы не используем "браузер", мы показываем tooltip,
	if(ie)
		$tooltip.css('left',left + 'px').show();
	else
	$tooltip.stop()
		.animate({
			left: left + 'px',
			opacity: 1
		},150);
}
 

Функция hideTooltip() скрывает миниатюру (или прячет, если браузер IE):

function hideTooltip(){
	//прячет / скрывает $tooltip
	if(ie)
		$tooltip.hide();
	else
	$tooltip.stop()
		.animate({
			opacity	: 0
		},150);
}
 

Следующая функция анимирует полное изображения с правой стороны. Новое изображение “становится на место”:

function showImage(e){
	var $link = $(this),
		idx = $link.index(),
		$image = $link.find('a').attr('href'),
		$currentImage = $ps_image_wrapper.find('img'),
		currentImageWidth = $currentImage.width();

	//если мы кликаем по точке с текущей позицией возвращаем false
	if(current == idx) return false;

	//добавляем класс selected для текущего изображения / точки
	$links.eq(current).removeClass('selected');
	$link.addClass('selected');

	//новый элемент изображения
	var $newImage = $('').css('left',currentImageWidth + 'px').attr('src',$image);

	//если в контейнере более одной фото, скрываем старые
	if($ps_image_wrapper.children().length > 1)
		$ps_image_wrapper.children(':last').remove();

	//добавляем новое изображение
	$ps_image_wrapper.prepend($newImage);

	//ширина новой фото
	//такой будет новая ширина ps_image_wrapper
	var newImageWidth = $newImage.width();

	//проверяем в какую сторону проводить анимацию
	if(current > idx){
		$newImage.css('left',-newImageWidth + 'px');
		currentImageWidth = -newImageWidth;
	}
	current = idx;
	//анимируем новую ширину ps_image_wrapper
	$ps_image_wrapper.stop().animate({
		width: newImageWidth + 'px'
	},350);
	//показываем новое фото
	$newImage.stop().animate({
		left: '0px'
	},350);
	//убираем старую фото
	$currentImage.stop().animate({
		left: -currentImageWidth + 'px'
	},350);

	e.preventDefault();
}
 

Функция навигации будет обрабатывать триггер click для каждой точки:

function nextImage(){
	if(current < total_images){ $links.eq(current+1).trigger('click'); } } function prevImage(){ if(current > 0){
		$links.eq(current-1).trigger('click');
	}
}
 

Вот и всё! Надеся, вам понравилось и вы примените эту галерею у себя на сайтах!


Источник урока: www.tympanus.net/codrops/2011/01/19/sweet-thumbnails-gallery/

 

 

Урок Создан:2011-05-13 Просмотров:2293

Добавить комментарий:


Copyright© 2009 Hosted by Zhost