Авторизация







Регистрация / Забыли пароль?

Регистрация нового пользователя











< Назад

Восстановление пароля





< Назад

Добро пожаловать

Выход


Ежедневное обновление статей и уроков, будь в курсе, держи руку на пульсе событий!

Главная >> jQuery

Элегантное слайд шоу с миниатюрами, имеющее потрясающий вид даже при небольших разрешениях экрана

Урок есть и в видеоформате! Смотреть?

Сегодня, мы хотим показаться вам, как создать простое адаптивное слайд – шоу с просмотром миниатюр. Оно будет автоматически подстраиваться под размеры блока в котором находится, а мы в это время сможем перемещаться по слайдам, как выбирая миниатюру, так просматривая в режиме авто листания.


    Для того чтобы заставить это слайд – шоу реагировать на пользовательские манипуляции, мы будем использовать смесь из 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 я остановился. Простота работы, вес самого плагина меня очень порадовали, поэтому поделюсь с вами я именно им, так как сам его проверял.

Уроки и статьи

«Найден Самый Дешевый и Эффективный Способ Рекламы в Интернете!»

Доказанo: ведение своей почтовой рассылки - это самый действенный и дешевый метод рекламы в Интернете.

Используете ли Вы его?

Если нет, то Вы давно теряете свои деньги! Если да, то пришло время вести Вашу почтовую рассылку на самом эффективном инструменте в Рунете - сервисе рассылок SmartResponder.ru

Узнать об этом подробнее >>

Быть в курсе всех событий: