Добрый день. Сегодня мы покажем вам небольшое руководство по созданию слайдера с эффектом параллакса на jQuery.
Какой толк от параллакса? Этот эффект добавит слайдеру «глубину» восприятия.
Разметка
HTML разметка начинается с основного контейнера с классом pxs_container
. Кроме того, мы добавим оболочку для трех различных бэкграундов, чтобы создать эффект параллакса. Изображения для фона полупрозрачны — иначе эффект не получится.
Еще в разметку войдут элементы анимации загрузки, два неупорядоченных списка изображений (основные и превьюшки), и, конечно, элементы навигации.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<div id="pxs_container" class="pxs_container"> <div class="pxs_bg"> <div class="pxs_bg1"></div> <div class="pxs_bg2"></div> <div class="pxs_bg3"></div> </div> <div class="pxs_loading">Loading images...</div> <div class="pxs_slider_wrapper"> <ul class="pxs_slider"> <li><img src="images/1.jpg" alt="First Image" /></li> <li><img src="images/2.jpg" alt="Second Image" /></li> ... </ul> <div class="pxs_navigation"> <span class="pxs_next"></span> <span class="pxs_prev"></span> </div> <ul class="pxs_thumbnails"> <li><img src="images/thumbs/1.jpg" alt="First Image" /></li> <li><img src="images/thumbs/2.jpg" alt="Second Image" /></li> ... </ul> </div> </div> |
Теперь разберемся со стилями.
CSS
Начнем с основного контейнера. Поскольку мы будем использовать всю ширину страницы для слайдера, поставим ширину основного контейнера на 100%. Установим его позиционирование на relative
, потому как всего элементы внутри него будут с позициями absolute
:
1 2 3 4 5 6 7 8 9 10 11 |
.pxs_container{ width:100%; height:420px; position:relative; border-top:7px solid #333; border-bottom:7px solid #333; overflow:hidden; -moz-box-shadow:0px 0px 7px #000; -webkit-box-shadow:0px 0px 7px #000; box-shadow:0px 0px 7px #000; } |
Оболочка для контейнеров с параллакс-изображениями будет содержать повторяемое фоновое изображение. Это изображение — простой градиент:
1 2 3 |
.pxs_bg{ background:transparent url(../images/bg.png) repeat top left; } |
У элементов DIV
внутри оболочки следующие свойства:
1 2 3 4 5 6 7 8 9 |
.pxs_bg div{ position:absolute; top:0px; left:0px; height:420px; background-repeat:repeat; background-position:top left; background-color:transparent; } |
Ширина будет устанавливаться динамически, с помощью JavaScript. Теперь назначим для каждого контейнера свое фоновое изображение:
1 2 3 4 5 6 7 8 9 |
.pxs_bg .pxs_bg1{ background-image:url(../images/bg1.png); } .pxs_bg .pxs_bg2{ background-image:url(../images/bg2.png); } .pxs_bg .pxs_bg3{ background-image:url(../images/bg3.png); } |
Также отметим, что и свойство left
, также будет изменятся динамически. Вернемся к нему позже.
В начале оболочка невидима:
1 2 3 |
.pxs_slider_wrapper{ display:none; } |
Она содержит все элементы, которые мы хотим загрузить. После того, как загрузка будет полностью проведена, мы покажем эту оболочку со всеми ее элементами.
Сбрасываем стили для списков:
1 2 3 4 5 |
.pxs_container ul{ margin:0px; padding:0px; list-style:none; } |
Основная идея слайдера состоит в том, что мы сделаем действительно длинный список всех элементов li
с шириной всего окна. И так, вы видите на экране слайдер — на самом деле это один элемент li
. Мы установим ширину элемента ul
динамически, исходя из совокупной ширины всех li
элементов. Установка свойства float:left
для всех li
, даст нам гарантию, что все li
элементы будут идти друг за другом:
1 2 3 4 5 6 7 8 9 10 11 |
ul.pxs_slider{ position:absolute; left:0px; top:0px; height:420px; } ul.pxs_slider li{ height:420px; float:left; position:relative; } |
Изображение в элементе li
оцентировано горизонтально с помощью свойства margin
на auto
слева и справа:
1 2 3 4 5 6 7 8 9 10 11 |
ul.pxs_slider li img{ display:block; margin:35px auto 0px auto; -moz-box-shadow:0px 0px 7px #222; -webkit-box-shadow:0px 0px 7px #222; box-shadow:0px 0px 7px #222; border: 8px solid transparent; -moz-border-radius:4px; -webkit-border-radius:4px; border-radius:4px; } |
Установкой прозрачного бордюра и тени мы добьемся эффекта стекла вокруг изображения.
Список превьюшек также спозиционирован абсолютно. Мы установим свойство left
на 50%, потому что хотим, чтобы этот список был всегда в центре окна. Свойства width
и отрицательный left margin
будут расчитываться с помощью JavaScript:
1 2 3 4 5 6 7 8 9 10 |
ul.pxs_thumbnails{ height:35px; position:absolute; top:320px; left:50%; } ul.pxs_thumbnails li{ position:absolute; display:block; } |
Добавим белый бордюр и тень вокруг превьюшек:
1 2 3 4 5 6 7 8 9 |
ul.pxs_thumbnails li img{ border: 5px solid #FFFFFF; -moz-box-shadow:1px 1px 7px #555; -webkit-box-shadow:1px 1px 7px #555; box-shadow:1px 1px 7px #555; cursor:pointer; display:block; opacity:0.7; } |
Активная превьюшка будет полностью видимой:
1 2 3 |
ul.pxs_thumbnails li.selected img{ opacity:1.0; } |
Стили для навигации следующие:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
.pxs_navigation span{ position:absolute; width:30px; height:60px; -moz-box-shadow:0px 0px 2px #000; -webkit-box-shadow:0px 0px 2px #000; box-shadow:0px 0px 2px #000; top:145px; opacity:0.6; -moz-border-radius:4px; -webkit-border-radius:4px; border-radius:4px; cursor:pointer; } .pxs_navigation span:hover{ opacity:0.9; } |
Добавим изображение стрелки для каждого элемента навигации span
:
1 2 3 4 5 6 |
.pxs_navigation span.pxs_prev{ background:#000 url(../images/prev.png) no-repeat center center; } .pxs_navigation span.pxs_next{ background:#000 url(../images/next.png) no-repeat center center; } |
Установка значений для left
(pxs_prev
) и right
(pxs_next
) будет автоматической, в расчете от ширины изображения.
И в конце добавим стили для элемента загрузки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
.pxs_loading{ color:#fff; font-size:20px; padding:15px 15px 15px 50px; position:absolute; background:#333 url(../images/ajax-loader.gif) no-repeat 10px 50%; -moz-border-radius:15px; -webkit-border-radius:15px; border-radius:15px; opacity:0.7; width:180px; position:absolute; top:150px; left:50%; margin-left:-90px; } |
Со стилями закончили, приступаем к jQuery!
JavaScript
Основная идея слайдера в том, чтобы при анимации прокрутки изображений менялся и фон слайдера в соответствии эффекту параллакса. Например, когда мы нажимаем на прокрутку, чтобы увидеть следующее изображение, мы меняем(анимируем) значение свойства left
для элемента ul
на ширину li
элемента. Также анимируем фоновые изображения, причем самое ближнее сдвинется на половину ширины экрана, чуть подальше на четверть, а еще дальше на одну восьмую. Это основной принцип параллакс эффекта.
Начнем с опций и кэширования.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 |
(function($) { $.fn.parallaxSlider = function(options) { var opts = $.extend({}, $.fn.parallaxSlider.defaults, options); return this.each(function() { var $pxs_container = $(this), o = $.meta ? $.extend({}, opts, $pxs_container.data()) : opts; //основной слайдер var $pxs_slider = $('.pxs_slider',$pxs_container), //элементы в слайдеры $elems = $pxs_slider.children(), //общее количество элементов total_elems = $elems.length, //навигационные кнопки $pxs_next = $('.pxs_next',$pxs_container), $pxs_prev = $('.pxs_prev',$pxs_container), //фоновые изображения $pxs_bg1 = $('.pxs_bg1',$pxs_container), $pxs_bg2 = $('.pxs_bg2',$pxs_container), $pxs_bg3 = $('.pxs_bg3',$pxs_container), //текущее изображение current = 0, //контейнер превьюшек $pxs_thumbnails = $('.pxs_thumbnails',$pxs_container), //превьюшки $thumbs = $pxs_thumbnails.children(), //интервал для режима автопрокрутки slideshow, //изображение загрузки $pxs_loading = $('.pxs_loading',$pxs_container), $pxs_slider_wrapper = $('.pxs_slider_wrapper',$pxs_container); //во-первых, предзагрузка всех изображений var loaded = 0, $images = $pxs_slider_wrapper.find('img'); $images.each(function(){ var $img = $(this); $('<img/>').load(function(){ ++loaded; if(loaded == total_elems*2){ $pxs_loading.hide(); $pxs_slider_wrapper.show(); //ширина изображения var one_image_w = $pxs_slider.find('img:first').width(); /* установки ширины слайдера */ setWidths($pxs_slider, $elems, total_elems, $pxs_bg1, $pxs_bg2, $pxs_bg3, one_image_w, $pxs_next, $pxs_prev); /* установка ширины для превьюшек */ $pxs_thumbnails.css({ 'width' : one_image_w + 'px', 'margin-left' : -one_image_w/2 + 'px' }); var spaces = one_image_w/(total_elems+1); $thumbs.each(function(i){ var $this = $(this); var left = spaces*(i+1) - $this.width()/2; $this.css('left',left+'px'); if(o.thumbRotation){ var angle = Math.floor(Math.random()*41)-20; $this.css({ '-moz-transform' : 'rotate('+ angle +'deg)', '-webkit-transform' : 'rotate('+ angle +'deg)', 'transform' : 'rotate('+ angle +'deg)' }); } //анимация превьюшек при наведении на них мышкой $this.bind('mouseenter',function(){ $(this).stop().animate({top:'-10px'},100); }).bind('mouseleave',function(){ $(this).stop().animate({top:'0px'},100); }); }); highlight($thumbs.eq(0)); //прокрутка при нажатии на навигационные кнопки $pxs_next.bind('click',function(){ ++current; if(current >= total_elems) if(o.circular) current = 0; else{ --current; return false; } highlight($thumbs.eq(current)); slide(current, $pxs_slider, $pxs_bg3, $pxs_bg2, $pxs_bg1, o.speed, o.easing, o.easingBg); }); $pxs_prev.bind('click',function(){ --current; if(current < 0) if(o.circular) current = total_elems - 1; else{ ++current; return false; } highlight($thumbs.eq(current)); slide(current, $pxs_slider, $pxs_bg3, $pxs_bg2, $pxs_bg1, o.speed, o.easing, o.easingBg); }); /* клик на превьюшке */ $thumbs.bind('click',function(){ var $thumb = $(this); highlight($thumb); if(o.auto) clearInterval(slideshow); current = $thumb.index(); slide(current, $pxs_slider, $pxs_bg3, $pxs_bg2, $pxs_bg1, o.speed, o.easing, o.easingBg); }); /* активация автопроигрывания, если данная опция определена */ if(o.auto != 0){ o.circular = true; slideshow = setInterval(function(){ $pxs_next.trigger('click'); },o.auto); } /* при изменении окна, нужно пересчитывать ширину элементов и их позиционирование; */ $(window).resize(function(){ w_w = $(window).width(); setWidths( $pxs_slider, $elems, total_elems, $pxs_bg1, $pxs_bg2, $pxs_bg3, one_image_w, $pxs_next, $pxs_prev ); slide( current, $pxs_slider, $pxs_bg3, $pxs_bg2, $pxs_bg1, 1, o.easing, o.easingBg ); }); } }).error(function(){ alert('here') }).attr('src',$img.attr('src')); }); }); }; //текущая ширина окна var w_w = $(window).width(); var slide = function(current, $pxs_slider, $pxs_bg3, $pxs_bg2, $pxs_bg1, speed, easing, easingBg){ var slide_to = parseInt(-w_w * current); $pxs_slider.stop().animate({ left : slide_to + 'px' },speed, easing); $pxs_bg3.stop().animate({ left : slide_to/2 + 'px' },speed, easingBg); $pxs_bg2.stop().animate({ left : slide_to/4 + 'px' },speed, easingBg); $pxs_bg1.stop().animate({ left : slide_to/8 + 'px' },speed, easingBg); } var highlight = function($elem){ $elem.siblings().removeClass('selected'); $elem.addClass('selected'); } var setWidths = function($pxs_slider, $elems, total_elems, $pxs_bg1, $pxs_bg2, $pxs_bg3, one_image_w, $pxs_next, $pxs_prev){ var pxs_slider_w = w_w * total_elems; $pxs_slider.width(pxs_slider_w + 'px'); $elems.width(w_w + 'px'); /* также устанавливаем ширину каждого div элемента для фона. Значение для всех pxs_slider */ $pxs_bg1.width(pxs_slider_w + 'px'); $pxs_bg2.width(pxs_slider_w + 'px'); $pxs_bg3.width(pxs_slider_w + 'px'); /* позиционирование элементов навигации */ var position_nav = w_w/2 - one_image_w/2 + 3; $pxs_next.css('right', position_nav + 'px'); $pxs_prev.css('left', position_nav + 'px'); } $.fn.parallaxSlider.defaults = { auto : 0, speed : 1000, easing : 'jswing', easingBg : 'jswing', circular : true, thumbRotation : true }; //easeInOutExpo,easeInBack })(jQuery); |
Добавим следующий скрипт для инициализации нашего слайдера:
1 2 3 4 |
$(function() { var $pxs_container = $('#pxs_container'); $pxs_container.parallaxSlider(); }); |
У слайдера есть следующие настраиваемые опции:
- auto: Время в секундах между прокрутками. Если установить на 0, тогда автопроигрывание отключится.
- speed: Скорость анимации между слайдами.
- easing: Эффект затухания для анимации прокрутки.
- easingBg: Эффект затухания для анимации фонов.
- circular: Цикличность.
- thumbRotation: Случайный поворот превьюшек.
Вот и все! Надеемся, что руководство было для вас полезным!
Спасибо огромное! Очень пришлась по душе данная фотогалерея, особенно из-за отсутствия «php» и «flash». Я лишь дружу с HTML и CSS — в результате чего данная галерея удобно внедряется в сайт либо переделывается в сайт. Вопрос: данная галерея бесплатная или нет?
бесплатная
не могу установить этот слайдер на сайте... поможете мне? спасибо!
что не получается?
подскажите как сделать просмотр циклический- по кругу... а не возвращаться через все на первый.