Предпросмотр миниатюр слайдами

В этом уроке я покажу, как можно сделать предпросмотр миниатюр слайдами на jQuery.

Разметка HTML

Структура HTML будет построена из контейнера - списка, который будет включать в себя элементы ввиде точек и специальный элемент списка для миниатюр. Специальный элемент списка будет иметь класс "ts_thumbnails" и будет содержать элемент с маленьким окном, в котором мы будем видеть миниатюры, как только наведем курсор на точку.

<ul class="ts_container">
    <li><a href="#">Image 1</a></li>
    <li><a href="#">Image 2</a></li>
    <li><a href="#">Image 3</a></li>
    <li><a href="#">Image 4</a></li>
    <li><a href="#">Image 5</a></li>
    <li><a href="#">Image 6</a></li>
    <li><a href="#">Image 7</a></li>
    <li><a href="#">Image 8</a></li>
    <li><a href="#">Image 9</a></li>
    <li><a href="#">Image 10</a></li>
    <li class="ts_thumbnails">
        <div class="ts_preview_wrapper">
            <!-- List with thumbnails/preview items -->
        </div>
        <span></span>
    </li>
</ul>

Пустой тег <span> будет содержать маленький треугольник, который указывает на текущую точку.
Список миниатюр, который будет внутри DIV с классом "ts_preview_wrapper" будет иметь следующий вид:

<ul class="ts_preview">
    <li><img src="images/thumbs1/1.jpg" alt="Thumb 1" /></li>
    <li><img src="images/thumbs1/2.jpg" alt="Thumb 2" /></li>
    <li><img src="images/thumbs1/3.jpg" alt="Thumb 3" /></li>
    <li><img src="images/thumbs1/4.jpg" alt="Thumb 4" /></li>
    <li><img src="images/thumbs1/5.jpg" alt="Thumb 5" /></li>
    <li><img src="images/thumbs1/6.jpg" alt="Thumb 6" /></li>
    <li><img src="images/thumbs1/7.jpg" alt="Thumb 7" /></li>
    <li><img src="images/thumbs1/8.jpg" alt="Thumb 8" /></li>
    <li><img src="images/thumbs1/9.jpg" alt="Thumb 9" /></li>
    <li><img src="images/thumbs1/10.jpg" alt="Thumb 10" /></li>
</ul>

CSS

Основной контейнер - список будет иметь относительное позиционирование и его ширина будет равна сумме ширин всех точек.

ul.ts_container{
    list-style:none;
    margin:0;
    padding:0;
    width:170px;
    margin:20px auto;
    position:relative;
    height:17px;
}

Как мы увидим позже, ширина точки 11px + отступ (padding) с каждой стороны 3px. Если вы будете использовать более 10 точек, то необходимо будет изменить значение ширины (а также и высоты) с учетом всех элементов.
Элементы списка, например точки, будут располагаться слева:

ul.ts_container li{
    float:left;
}

В качестве точек используется фоновая картинка, и текст имеет параметр indent:-9000px, чтобы его не было видно:

ul.ts_container li a{
    display:block;
    text-indent:-9000px;
    width:11px;
    height:11px;
    outline:none;
    padding:0px 3px;
    background:transparent url(../images/sliderIcons/dot.png) no-repeat top center;
}

При наведении курсора на точку изменяется положение фонового изображения так, что мы увидим его нижнюю часть, т. е. из светло-серой точка станет серой.

ul.ts_container li a:hover,
ul.ts_container li.selected a{
    background-position:50% -11px;
}

Последний элемент списка, который является специальным контейнером миниатюр будет иметь абсолютное позиционирование и изначально он будет не видимым.

ul.ts_container li.ts_thumbnails{
    display:none;
    position:absolute;
}

Пустой тег <span> содержащий маленький треугольник, будет позиционироваться динамически, т.к. зависит от размера миниатюры.

ul.ts_container li.ts_thumbnails span{
    background:transparent url(../images/sliderIcons/triangle.png) no-repeat top center;
    width:15px;
    height:6px;
    position:absolute;
}

Совет: Если вы считаете, что не очень удобно использовать в HTML пустые элементы, то просто добавьте какой то осмысленный текст, и добавьте значение text-indent с минусовым значением, чтобы текст не был виден. Теперь HTML будет более удобен для понимания.
Превьюшки будут обрамлены белой рамочкой с тенью. Размеры, опять же, формируются динамически, так как зависят от размера картинок. Выходы элементов за пределы рамки будут скрыты,так как будет ряд миниатюр в списке внутри этой рамочки:

.ts_preview_wrapper{
    border:5px solid #fff;
    overflow:hidden;
    position:relative;
    -moz-box-shadow:0px 0px 5px #999;
    -webkit-box-shadow:0px 0px 5px #999;
    box-shadow:0px 0px 5px #999;
}

Список всех миниатюр будет иметь абсолютное позиционирование:

ul.ts_preview{
    position:absolute;
    left:0px;
    top:0px;
    margin:0;
    padding:0;
    list-style-type:none;
}

Список элементов содержащие миниатюры будет придерживаться левой стороны:

ul.ts_preview li{
    float:left;
}

Миниатюры должны показываться, как блоки:

ul.ts_preview li img{
    display:block;
}

javascript

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

(function($) {
    $.fn.thumbnailSlider = function(options) {
        var opts = $.extend({}, $.fn.thumbnailSlider.defaults, options);
        return this.each(function() {
            ...
        });
    };
    $.fn.thumbnailSlider.defaults = {
        speed        : 100, //скорость анимации каждого слайда
        easing        : 'jswing', //легкий эффект для анимации слайда
        thumb_width    : 75, //ширина ваших фоток
        thumb_height: 75, //высота ваших фоток
        zoom        : false, //анимация увеличения для миниатюр
        zoomratio    : 1.3, //множитель для увеличения (должен быть > 1)
        zoomspeed    : 15000, //скорость анимации увеличения
        onclick        : function(){return false;} //вызов по клику
    };
})(jQuery);

Посмотрим на работу плагина более подробно. Во-первых, нужно определить несколько перменных:

var $this                 = $(this),
    o                     = $.meta ? $.extend({}, opts, $pxs_container.data()) : opts;

var $ts_container        = $this.children('.ts_container'),
    $ts_thumbnails        = $ts_container.children('.ts_thumbnails'),
    $nav_elems            = $ts_container.children('li').not($ts_thumbnails),
    total_elems            = $nav_elems.length,
    $ts_preview_wrapper    = $ts_thumbnails.children('.ts_preview_wrapper'),
    $arrow                = $ts_thumbnails.children('span'),
    $ts_preview            = $ts_preview_wrapper.children('.ts_preview');

Вычисление значения размеров для контейнера ts_thumbnails:

/*
calculate sizes for $ts_thumbnails:
width     -> width thumbnail + border (2*5)
height     -> height thumbnail + border + triangle height(6)
top        -> -(height plus margin of 5)
left    -> leftDot - 0.5*width + 0.5*widthNavDot
    this will be set when hovering a dot,
    and the default value will correspond to the first nav dot
*/
var w_ts_thumbnails    = o.thumb_width + 2*5,
    h_ts_thumbnails    = o.thumb_height + 2*5 + 6,
    t_ts_thumbnails    = -(h_ts_thumbnails + 5),
    $first_nav        = $nav_elems.eq(0),
    l_ts_thumbnails    = $first_nav.position().left - 0.5*w_ts_thumbnails + 0.5*$first_nav.width();

Теперь нужно установить эти значения:

$ts_thumbnails.css({
    width    : w_ts_thumbnails + 'px',
    height    : h_ts_thumbnails + 'px',
    top        : t_ts_thumbnails + 'px',
    left    : l_ts_thumbnails + 'px'
});

Следующий шаг это правильное позиционирование треугольника:

/*
calculate the top and left for the triangle/tooltip
top        -> thumb height + border(2*5)
left    -> (thumb width + border)/2 -width/2
*/
var t_arrow    = o.thumb_height + 2*5,
    l_arrow    = (o.thumb_width + 2*5) / 2 - $arrow.width() / 2;
$arrow.css({
    left    : l_arrow + 'px',
    top        : t_arrow + 'px',
});

Список ts_preview, который содержит все миниатюры, нуждается в задании ширины, которую мы вычислим путём умножения ширины миниатюры на общее количество миниатюр:

/*
calculate the $ts_preview width -> thumb width times number of thumbs
*/
$ts_preview.css('width' , total_elems*o.thumb_width + 'px');

Затем мы устанавливаем его ширину и высоту:

$ts_preview_wrapper.css({
    width    : o.thumb_width + 'px',
    height    : o.thumb_height + 'px'
});

Теперь определим, что будет происходить при наведении на элемент навигации, то есть в нашем случае на точки.
Если используется опция увеличения, то будет увеличиваться ширина и высота миниатюры:

$nav_elems.bind('mouseenter',function(){
    var $nav_elem    = $(this),
        idx            = $nav_elem.index();

    /*
    calculate the new left
    for $ts_thumbnails
    */
    var new_left    = $nav_elem.position().left - 0.5*w_ts_thumbnails + 0.5*$nav_elem.width();

    $ts_thumbnails.stop(true)
                  .show()
                  .animate({
                    left    : new_left + 'px'
                  },o.speed,o.easing);                  

    /*
    animate the left of the $ts_preview to show the right thumb
    */
    $ts_preview.stop(true)
               .animate({
                    left    : -idx*o.thumb_width + 'px'
               },o.speed,o.easing);

    //zoom in the thumb image if zoom is true
    if(o.zoom && o.zoomratio > 1){
        var new_width    = o.zoomratio * o.thumb_width,
            new_height    = o.zoomratio * o.thumb_height;

        //increase the $ts_preview width in order to fit the zoomed image
        var ts_preview_w    = $ts_preview.width();
        $ts_preview.css('width' , (ts_preview_w - o.thumb_width + new_width)  + 'px');

        $ts_preview.children().eq(idx).find('img').stop().animate({
            width        : new_width + 'px',
            height        : new_height + 'px'
        },o.zoomspeed);
    }        

}).bind('mouseleave',function(){
    //if zoom set the width and height to defaults
    if(o.zoom && o.zoomratio > 1){
        var $nav_elem    = $(this),
            idx            = $nav_elem.index();
        $ts_preview.children().eq(idx).find('img').stop().css({
            width    : o.thumb_width + 'px',
            height    : o.thumb_height + 'px'
        });
    }

    $ts_thumbnails.stop(true)
                  .hide();

}).bind('click',function(){
    var $nav_elem    = $(this),
        idx            = $nav_elem.index();

    o.onclick(idx);
});

СКАЧАТЬСкачек: 267
132,39 Kb
Кто скачал?

ДЕМОПосмотреть
пример