Элегантное слайд шоу с миниатюрами, имеющее потрясающий вид даже при небольших разрешениях экрана
Сегодня, мы хотим показаться вам, как создать простое адаптивное слайд – шоу с просмотром миниатюр. Оно будет автоматически подстраиваться под размеры блока в котором находится, а мы в это время сможем перемещаться по слайдам, как выбирая миниатюру, так просматривая в режиме авто листания.
Для того чтобы заставить это слайд – шоу реагировать на пользовательские манипуляции, мы будем использовать смесь из JavaScript функций и CSS стилей.
Сказочные фотографии, используемые для демонстрационного примера, предоставил нам Bartek Lurka, они в свою очередь находятся под лицензией Attribution-NonCommercial-NoDerivs 3.0 Unported License.
Давайте начинать!
Разметка
Мы создадим 2 неупорядоченных списка, один для больших изображений, а другой для создания навигации под ними и отображения миниатюр. Первый из этих списков получит класс «large slider», в нём будет содержаться увеличенное изображение и 2 заголовка, H2 и H3:
<div id="ei-slider" class="ei-slider"> <ul class="ei-slider-large"> <li> <img src="images/large/1.jpg" alt="image01" /> <div class="ei-title"> <h2>Creative</h2> <h3>Geek</h3> </div> </li> <li>...</li> </ul> <ul class="ei-slider-thumbs"> <li class="ei-slider-element">Current</li> <li> <a href="#">Slide 1</a> <img src="images/thumbs/1.jpg" alt="thumb01" /> </li> <li>...</li> </ul> </div>
Второй неупорядоченный список, будет содержать в себе элементы с абсолютным позиционированием (первый - элемент списка с классом «ei-slider-element», в котором будет находиться метка текущего выбранного изображения, второй – заголовок с якорем на миниатюру, и она сама чуть ниже).
С этим всё, а сейчас давайте добавим немного стиля для нашей разметки!
CSS
Во – первых, нам необходимо определить стиль для основного блока. Внутри него, у нас будет ползунок с миниатюрами и шириной в 100% ширины блока. Сам слайдер также будет иметь 100% ширины области просмотра, что даст возможность расширить его на всю ширину экрана. Но мы всегда можем изменить максимальную ширину, чтобы и на больших экранах слайдер смотрелся отлично:
.ei-slider{ position: relative; width: 100%; max-width: 1920px; height: 400px; margin: 0 auto; }
Во время загрузки изображения, мы будем показывать элемент со следующими стилями:
.ei-slider-loading{ width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; z-index:999; background: rgba(0,0,0,0.9); color: #fff; text-align: center; line-height: 400px; }
Неупорядоченный список для больших изображений будет занимать всё пространство, если что-то выходит за его пределы, оно будет скрыто:
.ei-slider-large{ height: 100%; width: 100%; position:relative; overflow: hidden; }
Элементы внутри него будут содержать изображения, и позиционироваться абсолютно. В зависимости от выбранной миниатюры, изображения будут сдвинуты влево или вправо:
.ei-slider-large li{ position: absolute; top: 0px; left: 0px; overflow: hidden; height: 100%; width: 100%; }
Ширину больших изображений будет устанавливать наш JavaScript, но в случае если у пользователя он отключен, мы всё равно отобразим их, задав ширину в 100%:
.ei-slider-large li img{ width: 100%; }
Заголовок к изображению будет позиционироваться абсолютно, находясь в одном элементе списка, он будет размещаться посередине, но с отступом с правой стороны и сверху, чтобы не накладываться на него, т.е. как в демонстрационном примере:
.ei-title{ position: absolute; right: 50%; margin-right: 13%; top: 30%; }
Давайте стилизуем наши теги заголовков:
.ei-title h2, .ei-title h3{ text-align: right; } .ei-title h2{ font-size: 40px; line-height: 50px; font-family: 'Playfair Display', serif; font-style: italic; color: #b5b5b5; } .ei-title h3{ font-size: 70px; line-height: 70px; font-family: 'Open Sans Condensed', sans-serif; text-transform: uppercase; color: #000; }
Навигационный список будет иметь небольшую высоту, всего 13 пикселей. Ширину по умолчанию, мы будем устанавливать во время инициализации нашего плагина в настройках. Максимальную же ширину, мы установим свойством max-width. Это сделает его резиновым, но при изменении размера окна, он автоматически изменит ширину, и не зайдёт за границы максимального значения, что удобно при больших разрешениях экрана.
.ei-slider-thumbs{ height: 13px; margin: 0 auto; position: relative; }
Сами элементы списка навигации, будут иметь относительное позиционирование:
.ei-slider-thumbs li{ position: relative; float: left; height: 100%; }
Элемент же ползунка, показывающий миниатюру для выбранного элемента списка навигации, будет позиционироваться абсолютно, и находиться в верхней части навигации:
.ei-slider-thumbs li.ei-slider-element{ top: 0px; left: 0px; position: absolute; height: 100%; z-index: 10; text-indent: -9000px; background: rgba(0,0,0,0.9); }
Чтобы показать связь между выбранным элементом навигации и возникшей миниатюрой, мы будем использовать белую тень. Давайте так же добавим плавный переход градиента фона к возникающей миниатюре, во время наведения курсора на элемент навигации:
.ei-slider-thumbs li a{ display: block; text-indent: -9000px; background: #666; width: 100%; height: 100%; cursor: pointer; box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.3), 0px 1px 0px 1px rgba(255,255,255,0.5); transition: background 0.2s ease; } .ei-slider-thumbs li a:hover{ background-color: #f0f0f0; }
Она будет располагаться абсолютно, и дополнительно мы создадим переход, чтобы получить небольшое отражение. Добавим max-width чтобы быть уверенными в том, что даже если разрешение экрана большое, миниатюра будет иметь такую же ширину как и элемент навигации:
.ei-slider-thumbs li img{ position: absolute; bottom: 50px; opacity: 0; z-index: 999; max-width: 100%; transition: all 0.4s ease; -webkit-box-reflect: below 0px -webkit-gradient( linear, left top, left bottom, from(transparent), color-stop(50%, transparent), to(rgba(255,255,255,0.3)) ); }
Для создания эффекта скольжения миниатюры при наведении курсора, мы сделаем её изначально прозрачной и чуть приподнятой вверх:
.ei-slider-thumbs li:hover img{ opacity: 1; bottom: 13px; }
И последнее, но не по значению, нам необходимо удостовериться в том, что если ширина экрана пользователя небольшая, то заголовок не помешает просмотру большого изображения. Для этого мы разместим его в нижней части изображения, и добавим белый полу-прозрачный фон:
@media screen and (max-width: 830px) { .ei-title{ position: absolute; right: 0px; margin-right: 0px; width: 100%; text-align: center; top: auto; bottom: 10px; background: rgba(255,255,255,0.9); padding: 5px 0; } .ei-title h2, .ei-title h3{ text-align: center; } .ei-title h2{ font-size: 20px; line-height: 24px; } .ei-title h3{ font-size: 30px; line-height: 40px; } }
Для случая, когда у пользователя отключен JavaScript, мы добавим ещё кое какие стили, чтобы убедиться что пользователь всё-таки увидит слайдер. Мы будем скрывать скользящую сверху миниатюру изображения в блоке навигации:
.ei-slider{ height: auto; } .ei-slider-thumbs{ display: none; } .ei-slider-large li{ position: relative; }
Ну вот и со стилями управились. Переходим к JavaScript!
JavaScript
Поскольку мы создаём плагин, для начала давайте рассмотрим определённые его настройки:
$.Slideshow.defaults = { // тип анимации: // "sides" : новые изображения появляются слева / справа // "center": новые изображения появляются в центре animation : 'sides', // sides || center // если установлено в < // true слайды будут автоматически сменять друг друга, // и остановятся лишь тогда, когда пользователь кликнет по миниатюре autoplay : false, // интервал смены слайдов slideshow_interval : 3000, // скорость течения анимации speed : 800, // сглаживание для эффекта анимации easing : '', // процент скорости для анимации заголовков. // Скорость = speed * titlesFactor titlesFactor : 0.60, // скорость анимации заголовков titlespeed : 800, // сглаживание для эффекта анимации заголовков titleeasing : '', // максимальная ширина для миниатюр в пикселях thumbMaxWidth : 150 };
Первой функцией которую мы напишем, будет _init, которой мы будем передавать параметры названий элементов и изображений, для применения к ним непрозрачности в 0. Мы так же создадим возможность предварительной загрузки изображений, и после этого, будем определять их размеры и положение, в соответствии с высотой и шириной слайдера. После, мы займёмся настройками миниатюр и установкой ширины для маркированного списка навигации.
Затем, мы должны показать первый слайд, а если параметр autoplay установлен в true, то начать сменять слайды в автоматическом режиме. Необходимо также инициализировать события касающиеся изменения размеров окна и кликов по миниатюрам:
_init : function( options ) { this.options = $.extend( true, {}, $.Slideshow.defaults, options ); // установка непрозрачности для элементов заголовка и изображений this.$imgItems.css( 'opacity', 0 ); this.$imgItems.find('div.ei-title > *').css( 'opacity', 0 ); // текущее значение видимости слайдера this.current = 0; var _self = this; // предварительная загрузка изображений // с добавлением состояния загрузки this.$loading = $('<div class="ei-slider-loading">Loading</div>').prependTo( _self.$el ); $.when( this._preloadImages() ).done( function() { // скрыть процесс загрузки _self.$loading.hide(); // вычислить размеры и размещение всех изображений _self._setImagesSize(); // настроить контейнер миниатюр _self._initThumbs(); // показать первое изображение _self.$imgItems.eq( _self.current ).css({ 'opacity' : 1, 'z-index' : 10 }).show().find('div.ei-title > *').css( 'opacity', 1 ); // если autoplay установлен в true if( _self.options.autoplay ) { _self._startSlideshow(); } // инициализация событий _self._initEvents(); }); },
Следующий код, является описанием функций о которых мы говорили выше:
_preloadImages : function() { // предварительная загрузка всех больших изображений var _self = this, loaded = 0; return $.Deferred( function(dfd) { _self.$images.each( function( i ) { $('<img>').load( function() { if( ++loaded === _self.itemsCount ) { dfd.resolve(); } }).attr( 'src', $(this).attr('src') ); }); } ).promise(); }, _setImagesSize : function() { < // сохранить ширину блока ei-slider this.elWidth = this.$el.width(); var _self = this; this.$images.each( function( i ) { var $img = $(this); imgDim = _self._getImageDim( $img.attr('src') ); $img.css({ width : imgDim.width, height : imgDim.height, marginLeft : imgDim.left, marginTop : imgDim.top }); }); }, _getImageDim : function( src ) { var $img = new Image(); $img.src = src; var c_w = this.elWidth, c_h = this.$el.height(), r_w = c_h / c_w, i_w = $img.width, i_h = $img.height, r_i = i_h / i_w, new_w, new_h, new_left, new_top; if( r_w > r_i ) { new_h = c_h; new_w = c_h / r_i; } else { new_h = c_w * r_i; new_w = c_w; } return {< width : new_w, height : new_h, left : ( c_w - new_w ) / 2, top : ( c_h - new_h ) / 2 }; }, _initThumbs : function() { // установить max-width для элементов слайдера исходя из опций плагина // а также, ширину каждого элемента навигации исходя из 100% / общее количество элементов this.$sliderElems.css({ 'max-width' : this.options.thumbMaxWidth + 'px', 'width' : 100 / this.itemsCount + '%' }); // установить max-width элемента навигации и показать его this.$sliderthumbs.css( 'max-width', this.options.thumbMaxWidth * this.itemsCount + 'px' ).show(); }, _startSlideshow : function() { var _self = this; this.slideshow = setTimeout( function() { var pos; ( _self.current === _self.itemsCount - 1 ) ? pos = 0 : pos = _self.current + 1; _self._slideTo( pos ); if( _self.options.autoplay ) { _self._startSlideshow(); } }, this.options.slideshow_interval); },
Функция _slideTo вплотную занимается переходами между слайдами. И в зависимости от выбранных настроек, будет обрабатываться появление нового слайда путём скольжения слева или справа исходя из выбранного положения миниатюры в неупорядоченном списке навигации, либо слайд-шоу, с использованием эффекта появления/исчезновения. Здесь также проводится работа с заголовками для изображений, которые мы договорились устанавливать в середине блока с большим изображением со смещением справа и сверху. Элемент ползунка обретёт возможность перехода к текущей миниатюре анимированным способом.
_slideTo : function( pos ) { // ничего не делать, если происходит многократное нажатие по одной и той же миниатюре if( pos === this.current || this.isAnimating ) return false; this.isAnimating = true; var $currentSlide = this.$imgItems.eq( this.current ), $nextSlide = this.$imgItems.eq( pos ), _self = this, preCSS = {zIndex : 10}, animCSS = {opacity : 1}; // если в опциях установлено значение появления изображений слевой/правой стороны if( this.options.animation === 'sides' ) { preCSS.left = ( pos > this.current ) ? -1 * this.elWidth : this.elWidth; animCSS.left = 0; } // анимация заголовков $nextSlide.find('div.ei-title > h2') .css( 'margin-right', 50 + 'px' ) .stop() .delay( this.options.speed * this.options.titlesFactor ) .animate({ marginRight : 0 + 'px', opacity : 1 }, this.options.titlespeed, this.options.titleeasing ) .end() .find('div.ei-title > h3') .css( 'margin-right', -50 + 'px' ) .stop() .delay( this.options.speed * this.options.titlesFactor ) .animate({ marginRight : 0 + 'px', opacity : 1 }, this.options.titlespeed, this.options.titleeasing ) $.when( // скрыть текущие заголовки $currentSlide.css( 'z-index' , 1 ).find('div.ei-title > *').stop().fadeOut( this.options.speed / 2, function() { // сброс стилей $(this).show().css( 'opacity', 0 ); }), // анимировать следующий слайд в $nextSlide.css( preCSS ).stop().animate( animCSS, this.options.speed, this.options.easing ), // "блоке слайд-шоу" передвигая на новую позицию this.$sliderElem.stop().animate({ left : this.$thumbs.eq( pos ).position().left }, this.options.speed ) ).done( function() { // сбросить значение $currentSlide.css( 'opacity' , 0 ).find('div.ei-title > *').css( 'opacity', 0 ); $nextSlide.css( 'z-index', 1 ); _self.current = pos; _self.isAnimating = false; }); },
В свою очередь функция _initEvents будет заниматься адаптацией изображений если изменятся размеры окна, а так же перемещать изображение миниатюры, на которую был наведён курсор мыши. Не забудем и по щелчку на миниатюре, показать необходимый слайд:
_initEvents : function() { var _self = this; // изменение размера окна $(window).on( 'smartresize.eislideshow', function( event ) { // изменение размера изображений _self._setImagesSize(); // сброс позиций миниатюр _self.$sliderElem.css( 'left', _self.$thumbs.eq( _self.current ).position().left ); }); // щелчок по миниатюрам this.$thumbs.on( 'click.eislideshow', function( event ) { if( _self.options.autoplay ) { clearTimeout( _self.slideshow ); _self.options.autoplay = false; } var $thumb = $(this), idx = $thumb.index() - 1; // исключить скольжение миниатюры _self._slideTo( idx ); return false; }); }
На этом наш сегодняшний урок подошёл к концу. Надеюсь, он вам понравился, и вы нашли его полезным и элегантным!
Материал взят из зарубежного источника. И представлен исключительно в ознакомительных целях.
Дата публикации: 24.03.2013
Опубликовал: Сергей Кашурин
Просмотров: 1179
Правила перепечатки
Правила перепечатки
Уважаемый посетитель сайта!Ниже преведены условия использования и перепечатки материалов сайта /
Все материалы данного сайта подготовлены для Вас лично мной.
Большая часть материалов сайта - это авторские уроки, остальные, это переводы уроков с английского языка на русский.
Если Вы решили использовать материалы данного сайта где-то на своих ресурсах или в рассылке, то соблюдайте следующие требования:
1. Урок или статья должны перепечатываться «как есть» с сохранением всех ссылок на источник урока, а если это перевод, то и на сайт, авторы которого подготовили его.
2. Ссылки на сайт источника и переводчика обязательно должны быть работоспособными (при нажатии по ссылке человек должен перейти на сайт автора/переводчика). Если Вы перепечатали какой-либо документ, обязательно проверьте ссылку на работоспособность.
3. Искажение информации об авторе, источнике, переводчике при перепечатке материалов запрещено!
4. Содержание урока или статьи при перепечатке не должно подвергаться модификациям и переделке. Все уроки и статьи, размещенные на сайте, должны перепечатываться как есть. Вы не имеете права урезать, исправлять или иным образом коверкать републикуемый документ.
С уважением, Сергей Кашурин– владелец сайта /
100 бесплатных PSD элементов для веб-дизайна и мобильных устройств.
Всем привет! Давайте сегодняшний день сделаем исключением, и вместо урока, посмотрим очень классные PSD заготовки для веб-сайтов и мобильных приложений которые вы сможете бесплатно скачать!
5 прекраснейших дизайнерских решений для ваших форм входа
Уважаемые друзья, в этом уроке, собраны 5 красивейших форм регистрации/авторизации, с пошаговым объяснением, и с возможность бесплатно скачать. Вы всё ещё думаете читать или нет? А кто-то уже вовсю пользуется ими!
arcticModal - простые модальные окна jQuery
В поисках простого плагина для создания модальных окон, я перепробовал кучу вариантов, наткнувшись на arcticModal я остановился. Простота работы, вес самого плагина меня очень порадовали, поэтому поделюсь с вами я именно им, так как сам его проверял.