Эластичное слайдшоу с миниатюрами
В данном уроке мы создадим эластичное слайдшоу с миниатюрами. Слайдшоу будет автоматически подстраиваться под содержащий его контейнер, навигация по слайдам осуществляется с помощью предварительного просмотра миниатюр, имеется опция автоматического проигрывания.
Для реализации функции адаптации будет использоваться смесь техник JavaScript и CSS.
Разметка HTML
Мы создадим два неупорядоченных списка. Один будет использоваться для основного слайдера, а другой - для миниатюр навигации, расположенных под большим изображением. Элементы "большого слайдера" содержат изображения и заголовки 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>Креативно</h2> <h3>Geek</h3> </div> </li> <li>...</li> </ul> <ul class="ei-slider-thumbs"> <li class="ei-slider-element">Current</li> <li> <a href="#">Слайд 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, но ее надо определить на случай отключения JavaScript:
.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 px. При инициализации нашего плагина мы установим ширину по умолчанию для миниатюр.
.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)) ); }
При наведении курсора мыши мы будем анимировать значения свойств opacity и bottom, так что элемент будет выскальзывать сверху:
.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
Так как мы создаем плагин, то рассмотрим сначала определение опций:
$.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 : '', // Максимальная ширина для миниатюр в px thumbMaxWidth : 150 };
В функции _init сначала устанавливается полная прозрачность элементов заголовков и изображений. Также предварительно загружаются изображения, после чего мы устанавливаем для них размер и положение в соответствии с шириной и высотой слайдера. Затем конфигурируем навигацию миниатюр, устанавливая ширину неупорядоченногосписка и его пунктов.
Затем выводим первый слайд и, если включена опция автопроигрвания, запускаем слайдшоу. После чего инициализируются обработчики событий для изменений размеров окна и нажатий на миниатюры:
_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 ); // Если включено автопроигрывание 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() { // Сохраняе ширину слайда 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 ); _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; }); }
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/9sREjnUTDqQ/lessons.php
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Все мы сидим в сточной канаве, но некоторые при этом смотрят на звезды Уайльд Оскар - (1854-1900) - английский писатель |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.