В этом уроке мы объединим свойство CSS, называемое z-index, с возможностями jQuery, для создания необычной фото галереи. С помощью z-index можно добиться очередности наложения слоёв друг на друга(например контейнеров div), в нашем случае в качестве примера будут использованы изображения. Ну а jQuery придаст всему этому визуальный эффект.
Займемся подготовкой разметки HTML
<!-- relevant for the tutorial - start --> <div class="grid_6 prefix_1 suffix_1" id="gallery"> <div id="pictures"> <img src="images/picture1.png" alt="" /> <img src="images/picture2.png" alt="" /> <img src="images/picture3.png" alt="" /> <img src="images/picture4.png" alt="" /> <img src="images/picture5.png" alt="" /> </div> <div class="grid_3 alpha" id="prev"> <a href="#previous">« Previous Picture</a> </div> <div class="grid_3 omega" id="next"> <a href="#next">Next Picture »</a> </div> </div> <!-- relevant for the tutorial - end -->
Мы создали главный контейнер <div> в котором расположили контейнер для фотографий и два элемента управления(«предыдущее» и «следующее» фото) для передвижения фотографий. Мы можем добавить любое количество фотографий, как мы хотим, так как по нашему сценарию картинки будут автоматически уложены поочередно и появление того или иного изображения на первом плане осуществляется динамически.
Вот CSS код для нашей галереи:
/* relevant for the tutorial - start */ #gallery { position: relative; } #pictures { position: relative; height: 408px; } #pictures img { position: absolute; top: 0; left: 0; } #prev, #next { margin-top: 30px; text-align: center; font-size: 2.0em; } /* relevant for the tutorial - end */
Как видите контейнер для фотографий(#pictures) имеет относительное(relative) положение и значение высоты(height) картинки. Самим же фото внутри контейнера, тем что с тегом <img>, присвоено абсолютное(absolute) позиционирование и теперь когда их отступы от верхнего левого угла вышестоящего <div> равны нулю, то они накладываются друг на друга. Таким образом, последняя картинка под номером «5» (в HTML разметке) на экране монитора окажется поверх остальных, а первая «1» расположится на последней позиции.
В примере галереи, были использованы изображения PNG, все они являются прозрачными и имеют одинаковую высоту и ширину. Чтобы создать эффект неопрятной кучи фотографий, каждая картинка имеет гладкую тень и повёрнута на определённый угол. Сделано это вручную с помощью Photoshop.
Принцип изменения Z-индекса
Z-индекс указывает местоположение фотографии, то есть на 1,2,3 и т.д. месте. Далее нам необходимо поменять их местами и тем самым поменять положение, например картинку №2 на №1, при этом остальные фото так же изменят позицию на одну единицу, то есть бывшая третья станет второй и т.д. Всё это осуществляется посредством скрипта.
$(document).ready(function() { //perform actions when DOM is ready var z = 0; //for setting the initial z-index's var inAnimation = false; //flag for testing if we are in a animation $('#pictures img').each(function() { //set the initial z-index's z++; //at the end we have the highest z-index value stored in the z variable $(this).css('z-index', z); //apply increased z-index to <img> }); function swapFirstLast(isFirst) { if(inAnimation) return false; //if already swapping pictures just return else inAnimation = true; //set the flag that we process a image var processZindex, direction, newZindex, inDeCrease; //change for previous or next image if(isFirst) { processZindex = z; direction = '-'; newZindex = 1; inDeCrease = 1; } //set variables for "next" action else { processZindex = 1; direction = ''; newZindex = z; inDeCrease = -1; } //set variables for "previous" action $('#pictures img').each(function() { //process each image if($(this).css('z-index') == processZindex) { //if its the image we need to process $(this).animate({ 'top' : direction + $(this).height() + 'px' }, 'slow', function() { //animate the img above/under the gallery (assuming all pictures are equal height) $(this).css('z-index', newZindex) //set new z-index .animate({ 'top' : '0' }, 'slow', function() { //animate the image back to its original position inAnimation = false; //reset the flag }); }); } else { //not the image we need to process, only in/de-crease z-index $(this).animate({ 'top' : '0' }, 'slow', function() { //make sure to wait swapping the z-index when image is above/under the gallery $(this).css('z-index', parseInt($(this).css('z-index')) + inDeCrease); //in/de-crease the z-index by one }); } }); return false; //don't follow the clicked link } $('#next a').click(function() { return swapFirstLast(true); //swap first image to last position }); $('#prev a').click(function() { return swapFirstLast(false); //swap last image to first position }); });
Давайте теперь разложим данный скрипт на куски и разберём кто за что отвечает.
$('#pictures img').each(function() { //set the initial z-index's z++; //at the end we have the highest z-index value stored in the z variable $(this).css('z-index', z); //apply increased z-index to <img> });
Вы наверное заметили, что атрибута z-index, ни в разметке html, ни в CSS нет. В нашем примере он устанавливается при помощи jQuery. После окончания цикла всем тегам IMG в контейнере фотографий присваивается порядковый номер и соответствующее Z-значение индекса в переменной z.
function swapFirstLast(isFirst) {
Мы используем одну и ту же функцию для кнопок «предыдущий» и «следующий» шаг, так как они делают в принципе одно и то же.
if(inAnimation) return false; //if already swapping pictures just return else inAnimation = true; //set the flag that we process a image
Для нас главное, чтобы происходил сдвиг лишь одной фотографии за клик. Переменная inAnimation определяет состояние процесса анимации. Если картинка находится в движении, то её нужно возвратить в исходное положение(заданное нами в CSS top: 0; left: 0;). Если это не так, то анимация наоборот приходит в действие при клике.
var processZindex, direction, newZindex, inDeCrease; //change for previous or next image if(isFirst) { processZindex = z; direction = '-'; newZindex = 1; inDeCrease = 1; } //set variables for "next" action else { processZindex = 1; direction = ''; newZindex = z; inDeCrease = -1; } //set variables for "previous" action
Так как мы используем одну функцию для двух процессов, мы должны установить необходимые переменные.
processZindex — это положение фото, которое скрипт должен обработать, либо рисунок будет находиться на переднем плане, либо на заднем.
direction — где картинка будет «оживать». Имеется ввиду под кучей фотографий (-) или наоборот.
newZindex будет присвоен картинкам в соответствии их расположения. (1) для последней позиции и самое высокое значение Z-индекс для первой.
переменная inDeCrease говорит, остальным фотографиям об увеличении(+1) или уменьшении(-1) Z-индекса на одну позицию
$('#pictures img').each(function() { //process each image
Происходит проверка Z-индекса всех изображений и его замена
if($(this).css('z-index') == processZindex) { //if its the image we need to process $(this).animate({ 'top' : direction + $(this).height() + 'px' }, 'slow', function() { //animate the img above/under the gallery (assuming all pictures are equal height) $(this).css('z-index', newZindex) //set new z-index .animate({ 'top' : '0' }, 'slow', function() { //animate the image back to its original position inAnimation = false; //reset the flag }); }); }
Проверяется какое изображение должно изменить своё положение(первое или последнее). Когда всё решено, мы идем дальше и оживляем фотографию, либо над или под остальной кучей фоток. После завершения этого, устанавливается новый Z-индекс для изображениий и всё возвращается в исходное положение.
else { //not the image we need to process, only in/de-crease z-index $(this).animate({ 'top' : '0' }, 'slow', function() { //make sure to wait swapping the z-index when image is above/under the gallery $(this).css('z-index', parseInt($(this).css('z-index')) + inDeCrease); //in/de-crease the z-index by one }); }
Здесь мы заканчиваем с элементами управления «предыдущий» и «следующий». Во время работы скрипта клики по ссылкам блокируются.
Заключение
Итак мы создали приятную глазу галерею с помощью нескольких строк кода. Конечно, она может быть расширена добавлением новых функций(например, выборочный контроль фотографий, показ случайных позиции каждый раз и т.д.), но зато Вы получили представление о том, как совместить CSS и собственно магию JQuery. Меняйте код по Вашим потребностям и было бы совсем замечательно, если эти изменения стали доступны в комментариях.