Как я обещал в своей прошлой статье (Загрузка изображений с заданным разрешением в WordPress), представляю руководство по созданию галереи изображений заданного размера. В качестве бонуса вы также научитесь создавать базовый jQuery плагин, чтобы отображать увеличенное изображение миниатюры покрасивее.

Если вы не читали мою предыдущую статью о собственных размерах изображений, пожалуйста, прочтите ее, чтобы проще понять это руководство.

| Скачать исходники |

Шаг 1. Определитесь с размерами изображений

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

Я буду использовать ширину 940 px, 2х-колоночную разметку (8/4) в качестве примера, где контент будет 620 px, сайдбар — 300 px с 20 px левым отступом. Область контента и сайдабара будет иметь внутренние поля в 20 px.

Теперь немного математики: контент шириной в 600 px с 20 px интервалом, остается 580 px под миниатюры; если выводить их 5 в ряд, при этом у каждой будет отступ справа в 10 px, чтобы они не прилипали друг к другу, у пятой миниатюры в ряду не будет правого отступа. Миниатюры будут 108 px в высоту и ширину и обрезанные.

Увеличенные изображения будут максимум 660 px в ширину и высоту, они будут уменьшены пропорционально, без обрезки.

Вы можете выбрать размеры, которые подходят под вашу разметку, если вы решите изменить размеры, они могут быть легко обновлены (смотрите предыдущую статью чтобы узнать, как это сделать), и они не обязательно должны быть квадратными.

Шаг 2. Установка собственных размеров

Отредактируйте файл functions.php, чтобы он выглядел примерно так:

add_action( 'after_setup_theme', 'setup' );
function setup() {
	// ...

	add_theme_support( 'post-thumbnails' );
	add_image_size( 'preview', 108, 108, true ); // thumbnail
	add_image_size( 'zoomed', 660, 600 ); // large

	// ...
}

Шаг 3. Генерация списка миниатюр

Все в том же functions.php добавьте метод generate_thumbnail_list:

function generate_thumbnail_list( $post_id = null ) {
	if ( $post_id == null ) return;
	$images = get_posts(
		array(
			'numberposts' => -1,
			'post_type' => 'attachment',
			'post_mime_type' => 'image/jpeg, image/jpg, image/png, image/gif',
			'post_parent' => $post_id,
			'orderby' => 'menu_order',
			'order' => 'ASC',
			'exclude' => get_post_thumbnail_id( $post_id )
		)
	);
	if ( count( $images ) > 0 ) {
		echo '<ul class="gallery">';
		foreach ( $images as $image ) {
			$src = wp_get_attachment_image_src($image->ID, 'zoomed');
			echo '<li><a href="' . $src[0] .'">' . wp_get_attachment_image( $image->ID, 'preview' ) . '</a></li>';
		}
		echo '</ul>';
		echo '<div class="clear"></div>';
	}
}

В файле content-single.php вызовите метод generate_thumbnail_list, передавая ID поста в качестве параметра.

<?php the_content(); ?>  
<h3>Images</h3>  
<?php generate_thumbnail_list( get_the_ID() ); ?>

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

Шаг 4. Стилизация галереи

Очевидно, что миниатюрам нужно добавить оформление стиля, иначе это просто список изображений. Добавьте следующее в вашу таблицу стилей style.css:

.clear {
	clear: both;
}
.gallery {
	list-style-type: none;
	padding: 0;
	margin: 0;
}
.gallery li {
	float: left;
	margin: 0 10px 10px 0;
}
.gallery li:nth-child(5n) {
	margin-right: 0;
}
.gallery a {
	float: left;
	cursor: pointer;
	text-decoration: none;
}
.gallery img {
	float: left;
	border: 0;
}

Так мы разместим изображения рядом, оставляя между ними некоторое пространство.

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

Шаг 5. Открытие изображений с помощью галереи на jQuery

Стиль галереи с увеличенным изображением

Перед тем, как писать какой-либо JavaScript, было бы хорошо узнать, как большие изображения будут отображаться. Вот что я имел в виду:

Обратите внимание: все это будет генерироваться плагином jQuery. Я лишь хочу показать процесс создания.

Прозрачный слой поверх контента с изображением в центре и кнопками управления в правом верхнем углу. Пока изображение грузится, будет показываться символ загрузки. В тело документа будет добавлен слой-контейнер, который будет содержать ссылки для навигации на следующее и предыдущее изображение, ссылку на закрытие галереи и контейнер вокруг изображения, в который оно, собственно, и будет загружаться.

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

<div id="zoom">
	<a href="#next" class="next">Next</a>
	<a href="#previous" class="previous">Previous</a>
	<div class="close"></div>
	<div class="content"></div>
</div>

Если добавить код, приведенный ниже, к описанию стилей в файл style.css, получится такое же оформление, как показано на картинке выше:

#zoom {
	z-index: 99990; /* high index so it stays on top of all other elements */
	position: fixed; /* is fixed so if content is scrolled this stays in the same place */
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	/* creates a transparent background, so the content under it will be visible,
	transparency can be adjusted */
	background: rgba(0, 0, 0, 0.8);
}
#zoom .content {
	z-index: 99991; /* higher index so the image will stay on top of the overlay */
	position: absolute;
	/* start initial positioning: will be centered horizontally and vertically */
	top: 50%;
	left: 50%;
	width: 200px;
	height: 200px;
	margin: -100px 0 0 -100px;
	/* end positioning */
	/* an animated spinner as background will be visible while the image is loading */
	background: #ffffff url('../img/spinner.gif') no-repeat 50% 50%;
	border: 20px solid #ececec;
	padding: 0;
}
#zoom img {
	display: block;
	max-width: none;
	background: #ececec;
	-moz-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
	-webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
	box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.4);
}
#zoom .close {
	z-index: 99993; /* higher index so the close will stay above the overlay and image */
	position: absolute;
	top: 0;
	right: 0;
	width: 49px;
	height: 49px;
	cursor: pointer;
	background: transparent url('../img/icons/close.png') no-repeat 50% 50%;
	opacity: 1;
	filter: alpha(opacity=100);
}
#zoom .previous,
#zoom .next {
	z-index: 99992; /* higher index so the close will stay above the overlay and image */
	position: absolute;
	top: 0;
	overflow: hidden;
	display: block;
	width: 49px;
	height: 49px;
	text-indent: 100%;
}
#zoom .previous {
	right: 100px;
	background: url('../img/icons/arrows.png') no-repeat 0 0;
}
#zoom .next {
	right: 50px;
	background: url('../img/icons/arrows.png') no-repeat 100% 0;
}
#zoom .close:hover {
	background-color: #da4f49; /* adds a red tint on hover */
}
#zoom .previous:hover,
#zoom .next:hover {
	background-color: #0088cc; /* adds a blue tint on hover */
}

Из этого получим на выходе:

Теперь немного JavaScript

Приведенный выше HTML код будет не нужен, он будет генерироваться JavaScript. События будут привязаны к открытию, навигации или закрытию галереи. Навигация и закрытие галереи может осуществляться с клавиатуры или с помощью мышки.

JavaScript ниже также прокомментирован, чтобы пояснить, что происходит:

(function($) {
	$.zoom = function() {
		 // append a gallery wrapper to the document body
		$('body').append('<div id="zoom"></div>');
		var zoomedIn = false,  // a flag to know if the gallery is open or not
		    zoom = $('#zoom'),
		    zoomContent = null,
		    opened = null; // the opened image element

		function setup() {
			zoom.hide(); // hide it
			// add the inner elements, image wrapper, close and navigation links
			zoom.prepend('<div class="content"></div>');
			zoom.prepend('<div class="close"></div>');
			zoom.prepend('<a href="#previous" class="previous">Previous</a>');
			zoom.prepend('<a href="#next" class="next">Next</a>');

			zoomContent = $('#zoom .content');
			// attach events to the added elements
			$('#zoom .close').on('click', close);
			$('#zoom .previous').on('click', openPrevious);
			$('#zoom .next').on('click', openNext);

			// observe keyboard events for navigation and closing the gallery
			$(document).keydown(function(event) {
				if (!opened) {
					return;
				}
				if (event.which == 27) {
					$('#zoom .close').click();
					return;
				}
				if (event.which == 37) {
					$('#zoom .previous').click();
					return;
				}
				if (event.which == 39) {
					$('#zoom .next').click();
					return;
				}
				return;
			});

			if ($('.gallery li a').length == 1) {
				// add 'zoom' class for single image so the navigation links will hide
				$('.gallery li a')[0].addClass('zoom');
			}
			// attach click event observer to open the image
			$('.zoom, .gallery li a').on('click', open);
		}

		function open(event) {
			event.preventDefault(); // prevent opening a blank page with the image
			var link = $(this),
			    src = link.attr('href'),
				// create an image object with the source from the link
			    image = $(new Image()).attr('src', src).hide();
			if (!src) {
				return;
			}
			$('#zoom .previous, #zoom .next').show();
			if (link.hasClass('zoom')) {
				$('#zoom .previous, #zoom .next').hide();
			}

			// show the gallery with loading spinner, navigation and close buttons
			if (!zoomedIn) {
				zoomedIn = true;
				zoom.show();
			}

			// clean up and add image object for loading
			zoomContent.empty().prepend(image);
			// event observer for image loading, render() will be
			// called while image is loading
			image.load(render);
			opened = link;
		}

		function openPrevious(event) {
			event.preventDefault();
			if (opened.hasClass('zoom')) {
				return;
			}
			var prev = opened.parent('li').prev();
			if (prev.length == 0) {
				prev = $('.gallery li:last-child');
			}
			prev.children('a').trigger('click');
		}

		function openNext(event) {
			event.preventDefault();
			if (opened.hasClass('zoom')) {
				return;
			}
			var next = opened.parent('li').next();
			if (next.length == 0) {
				next = $('.gallery li:first-child');
			}
			next.children('a').trigger('click');
		}

		function render() {
			// if the image is not fully loaded do nothing
			if (!this.complete) {
				return;
			}
			var image = $(this);
			// if image has the same dimensions as the gallery
			// just show the image don't animate
			if (image.width() == zoomContent.width() &&
			    image.height() == zoomContent.height()) {
				show(image);
				return;
			}
			var borderWidth = parseInt(zoomContent.css('borderLeftWidth'));
			// resize the gallery to the image dimensions before
			// displaying the image
			zoomContent.animate({
				width: image.width(),
				height: image.height(),
				marginTop: -(image.height() / 2) - borderWidth,
				marginLeft: -(image.width() / 2) - borderWidth
			}, 300, function(){
				show(image);
			});

			function show(image) {
				image.fadeIn('fast');
			}
		}

		function close(event) {
			event.preventDefault();
			zoomedIn = false;
			zoom.hide();
			zoomContent.empty();
		}

		setup();
	};
})(jQuery);

После добавления плагина, инициализируйте его, добавив вызов плагина в метод generate_thumbnail_list.

function generate_thumbnail_list( $post_id = null ) {
	// ...
	if ( count( $images ) > 0 ) {
		// ...
		echo '<script type="text/javascript">jQuery.zoom();</script>';
	}
}

Пример

Пример того, как это работает в жизни и как может быть использовано: Zoom jQuery Photo Gallery Plugin demo

Источник: WP.tutsplus.com

Вам понравился материал?

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

Такой e-mail уже зарегистрирован. Воспользуйтесь формой входа или введите другой.

Вы ввели некорректные логин или пароль

Извините, для комментирования необходимо войти.

3 комментария

сначала новые
по рейтингу сначала новые по хронологии

Ссылка с примером - Page not found

Александр

Здравствуйте, давно искал нечто подобное, Шаг 2, 3 очень пригодился. Добавил свои стили и все что хотел реализовал без проблем, спасибо огромное.

Александр

Только вот вопрос, как заменить class="" к картинке wp_get_attachment_image( $image->ID, 'preview' ), стоит class="attachment-preview"

и как удалить width и height ????