Создаем объемный слайдер для сайта на jQuery
Пожалуй каждый из вас хоть раз, но уже встречал объемные слайдера на сайтах, это весьма правильный подход к организации контента, ведь необходимая информация находится постоянно на виду, да еще оформлена должным образом наверняка привлечет взор обычного читателя. С каждым днем посетителей и веб-мастеров становится тяжело удивить, ведь выходят новые скрипты, которые позволяют существенно расширить возможности при создании сайта. В сегодняшнем уроке мы рассмотрим детально, как создать один из таких объемных ротаторов изображений.
Слайдер достаточно красиво выглядит, но имеет небольшой недостаток, ведь будет работать в браузерах поддерживающие трансформации CSS3. Изображения были предоставлены geishaboy500 и находятся под лицензией Creative Commons Attribution 2.0 Generic (CC BY 2.0). И так, приступим.
Шаг 1. HTML
Для начала рассмотрим разметку HTML, которая будет содержать в себе блоки с фигурами, при этом каждая фигура будет содержать изображение и подпись к нему.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<div class="fs-slider" id="fs-slider"> <figure> <img src="images/1.jpg" alt="image01" /> <figcaption> <h3>Заголовок</h3> <p>Небольшое описание изображения. </p> </figcaption> </figure> <figure> <img src="images/2.jpg" alt="image02" /> <figcaption> <h3>Заголовок</h3> <p>Небольшое описание изображения.</p> </figcaption> </figure> </div> |
Данный плагин jQuery преобразует выше приведенную структуру в следующую.
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 |
<section class="fs-container"> <div class="fs-wrapper"> <div class="fs-slider" id="fs-slider"> <div class="fs-block"> <figure style="display: block; "> <img src="/images/1.jpg" alt="image01" /> <figcaption> <h3>Заголовок</h3> <p>Небольшое описание изображения. </p> </figcaption> </figure> </div><!-- /fs-block --> <div class="fs-block"> <!-- ... --> </div> <!-- ... --> </div><!-- /fs-slider --> <nav class="fs-navigation"> <span>Назад</span> <span>Вперед</span> </nav> </div><!-- /fs-wrapper --> </section><!-- /fs-container --> |
При этом каждая фигура будет с оболочкой в div с классом fs-block, а также добавим навигацию.
Шаг 2. CSS
Для начала мы установим ширину слайдера в процентах для повышения быстродействия, при этом мы определили минимальную и максимальную ширину. Так чтобы все изображения находились пропорционально.
1 2 3 4 5 6 7 8 9 10 |
.fs-container { margin: 20px auto 50px auto; position: relative; width: 40%; padding: 0 15%; max-width: 700px; min-width: 220px; height: 500px; box-sizing: content-box; } |
Теперь добавим тень и фоновое изображение.
1 2 3 4 5 6 7 8 9 10 11 |
.fs-container:before { content: ''; position: absolute; bottom: -40px; background: transparent url(../images/shadow.png) no-repeat center center; height: 90px; width: 90%; left: 5%; opacity: 0.8; background-size: 100% 100%; } |
Для перспективы добавим дополнительную оболочку.
1 2 3 4 5 6 |
.fs-wrapper { width: 100%; height: 100%; position: relative; perspective: 1000px; } |
При этом слайдер должен иметь 3d transform-style:
1 2 3 4 5 6 7 |
.fs-slider{ width: 100%; height: 100%; position: absolute; transform-style: preserve-3d; pointer-events: none; } |
Каждый из центровых блоков будет иметь ширину в 70%, а левое значение 15%, также добавляем переходы к дополнительным блокам.
1 2 3 4 5 6 7 8 9 |
.fs-block { margin: 0; position: absolute; width: 70%; height: 100%; left: 15%; pointer-events: auto; transition: all 1s ease; } |
Далее происходит правильное размещение блоков, Первый будет установлен слева при помощи translateX со значением -100%. Поворачивая его на -35 градусов по оси Y, мы достигнем эффекта отдаленности от центрального блока:
1 2 3 4 |
.fs-block:nth-child(1) { transform-origin: top right; transform: translateX(-100%) rotateY(-35deg); } |
При наведении на крайние блоки они будут немного выдвигаться вперед, для этого будем использовать Modernizr, который не работает на сенсорных девайсах.
1 2 3 |
.no-touch .fs-block:nth-child(1):hover { transform: translateX(-100%) rotateY(-30deg); } |
Теперь для передней панели установим z-index со значением 100, так как она должна находиться поверх остальных слайдов.
1 2 3 |
.fs-block:nth-child(2) { z-index: 100; } |
Теперь устанавливаем блок справа:
1 2 3 4 |
.fs-block:nth-child(3) { transform-origin: top left; transform: translateX(100%) rotateY(35deg); } |
Затем придаем блоку небольшой поворот.
1 2 3 |
.no-touch .fs-block:nth-child(3):hover { transform: translateX(100%) rotateY(30deg); } |
Теперь сделаем блоки более реалистичными, для этого добавим псевдо-класс :after и добавим рамку шириной 1px (чтобы устранить разрыв между панелями).
1 2 3 4 5 6 7 8 9 10 11 12 |
.fs-block:after{ content: ''; position: absolute; width: 100%; height: 100%; z-index: 1000; pointer-events: none; box-sizing: content-box; border-left: 1px solid rgba(119,119,119,1); border-right: 1px solid rgba(119,119,119,1); left: -1px; } |
Каждый блок имеет различный тип градиента.
1 2 3 4 5 6 7 8 |
.fs-block:nth-child(1):after { background: linear-gradient( to right, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.2) 100% ); } |
Теперь придаем градиент для центральной панели, он придаст ей эффект изогнутости.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.fs-block:nth-child(2):after { opacity: 0.8; background: linear-gradient( to right, rgba(0,0,0,0.5) 0%, rgba(0,0,0,0.12) 21%, rgba(0,0,0,0.03) 31%, rgba(0,0,0,0) 50%, rgba(0,0,0,0.03) 70%, rgba(0,0,0,0.12) 81%, rgba(0,0,0,0.5) 100% ); } |
Теперь разработаем элементы фигур. Зададим позицию и заполним ими весь блок.
1 2 3 4 5 6 7 8 9 10 |
.fs-block figure { width: 100%; height: 100%; margin: 0; position: absolute; top: 0; left: 0; overflow: hidden; z-index: 1; } |
Изображения должны иметь абсолютную позицию.
1 2 3 4 5 6 |
.fs-block figure img { position: absolute; top: 0; left: 0; display: block; } |
Теперь стиль для текста.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
.fs-block figcaption h3 { font-size: 40px; line-height: 40px; margin: 0; padding: 20px 0; color: #fff; text-shadow: 1px 1px 1px rgba(0,0,0,0.3); font-family: 'Prata', serif; font-weight: normal; } .fs-block figcaption p { color: #fff; padding: 20px 0; margin: 0; text-shadow: 1px 1px 1px rgba(0,0,0,0.2); border-top: 1px solid rgba(255,255,255,0.2); box-shadow: 0 -1px 0 rgba(0,0,0,0.3); } |
Навигация будет находиться внизу слайда.
1 2 3 4 5 6 7 8 |
.fs-navigation { position: absolute; z-index: 2000; bottom: 10px; right: 15%; margin-right: 15px; user-select: none; } |
Немного стилизуем стрелки, сделаем их более эластичными.
1 2 3 4 5 6 7 8 9 10 11 12 |
.fs-navigation span { float: left; width: 26px; height: 26px; border-radius: 4px; text-indent: -90000px; cursor: pointer; opacity: 0.6; margin-right: 3px; background: rgba(0,0,0,0.4) url(../images/arrow.png) no-repeat 50% 50%; pointer-events: auto; } |
Шаг 3. JavaScript
В опциях можно задать опции автоматического воспроизведения.
1 2 3 4 |
$.ImgSlider.defaults = { autoplay : false, interval : 4000 }; |
Сделаем предварительную загрузку всех изображений, после этого выполним функции _init:
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 |
_init : function( options ) { // опции this.options = $.extend( true, {}, $.ImgSlider.defaults, options ); this.current = 0; // https://github.com/twitter/bootstrap/issues/2870 var transEndEventNames = { 'WebkitTransition' : 'webkitTransitionEnd', 'MozTransition' : 'transitionend', 'OTransition' : 'oTransitionEnd', 'msTransition' : 'MSTransitionEnd', 'transition' : 'transitionend' }; this.transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ]; // инициализация элементов this.$initElems = this.$el.children( 'figure' ); // tобщее количество элементов this.initElemsCount = this.$initElems.length; if( this.initElemsCount < 3 ) { return false; } // расположение this._layout(); // события init this._initEvents(); // автовоспроизведение if( this.options.autoplay ) { this._startSlideshow(); } } |
Мы также должны изменить размер каждого изображения в соответствии с размером её оболочки. Описание элемента отображается только у центральной панели.
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 |
_initNavigationEvents : function() { var _self = this; this.$navPrev.on( 'click.imgslider', function() { if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'left' ); } ); this.$navNext.on( 'click.imgslider', function() { if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } _self._navigate( 'right' ); } ); } _navigate : function( dir ) { if( this.isAnimating === true ) { return false; } this.isAnimating = true; var _self = this, $items = this.$temp.children(), LIndex, CIndex, RIndex; this.$blocks.find( 'figcaption' ).hide().css( 'transition', 'none' ).removeClass( 'fs-transition' ); if( dir === 'right' ) { LIndex = this.current + 1; CIndex = this.current + 2; RIndex = this.current + 3; if( LIndex >= this.initElemsCount ) { LIndex -= this.initElemsCount } if( CIndex >= this.initElemsCount ) { CIndex -= this.initElemsCount } } else if( dir === 'left' ) { LIndex = this.current - 1; CIndex = this.current; RIndex = this.current + 1; if( LIndex < 0 ) { LIndex = this.initElemsCount - 1 } } if( RIndex >= this.initElemsCount ) { RIndex -= this.initElemsCount } var $elL = $items.eq( LIndex ).clone().show(), $elC = $items.eq( CIndex ).clone().show(), $elR = $items.eq( RIndex ).clone().show(); // изменение размеров изображений $elL.children( 'img' ).css( this.$blockL.data( 'imgstyle' ) ); $elC.children( 'img' ).css( this.$blockC.data( 'imgstyle' ) ); $elR.children( 'img' ).css( this.$blockR.data( 'imgstyle' ) ); this.$blockL.append( $elL ); this.$blockC.append( $elC ); this.$blockR.append( $elR ); // отображение новых изображений var $slides = this.$blocks.find( 'figure:first' ).css( 'width', '0%'); if( Modernizr.csstransitions ) { $slides.on( this.transEndEventName, function( event ) { var $this = $( this ), blockIdx = $this.parent().index(''); _self._slideEnd( dir, blockIdx, $elC ); $this.off( _self.transEndEventName ).remove(); } ); } else { $slides.each( function() { var $this = $( this ), blockIdx = $this.parent().index(''); _self._slideEnd( dir, blockIdx, $elC ); } ); this._slideEnd(); } } |
Далее мы должны позаботиться об изменении размеров окна. Если пользователь меняет размер окна, мы должны изменить размеры изображений соответственно. Это происходит при вызове функции_layout:
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 |
_initEvents : function() { var _self = this; $window.on( 'debouncedresize.imgslider', function() { _self._resizeBlocks(); } ); }, // Изменение размеров _resizeBlocks : function() { var _self = this; this.$blocks.each( function( i ) { var $el = $( this ).children( 'figure' ), $img = $el.children( 'img' ), dim = _self._getImageDim( $img.attr( 'src' ), { width : $el.width(), height : $el.height() } ); // Сохранение размеров switch( i ) { case 0 : _self.$blockL.data( 'imgstyle', dim ); break; case 1 : _self.$blockC.data( 'imgstyle', dim ); break; case 2 : _self.$blockR.data( 'imgstyle', dim ); break; }; // Применение стиля $img.css( dim ); } ); } |
Вот и все. Готово!
Материал взят из зарубежного источника. И представлен исключительно в ознакомительных целях.
Читайте также:
Опубликовал Cooper 17.10.2012 в 19:03, в категории CSS. Вы можете следить за комментариями через RSS 2.0. Вы можете перейти в конец записи и оставить комментарий. Пинги запрещены. |