7 декабря 2013
4545
до и после, jquery

До и после jQuery

JQuery
Демонстрация » Скачать »

В данном уроке я проиллюстрирую красивый анимированный эффект для просмотра фотографий типа до и после, который достигнут средствами jQuery. Сначала рассмотрим структуру объектов. Основная часть представляет собой следующий набор HTML тегов:

 

<div id="wrap">
       <div class="before">
                <img src="img/b1.jpg">
       </div>
       <div class="after">
                <img src="img/a1.jpg">
       </div>
</div>

 

 

Так же сразу приведу стили, примененные к этим элементам.

 

#wrap{
         width:330px;
         height:330px;
         position:relative;
}

#wrap .before{
         width:50%;
         position:relative;
         overflow:hidden;
         z-index:1000;
}

#wrap .after{
         position:absolute;
         top:0;
         left:0;
}

#wrap img{
         width:330px;
         height:330px;
}

 

Как видите, блок с идентификатором wrap является родительским блоком, относительно которого позиционируется все его содержимое.

Изображения внутри блоков с классами before и after имеют тот же размер что и блок wrap, а сами блоки before и after размещены один поверх другого, где за счет ширины верхнего блока можно открыть нижнее изображение.

 

Далее при помощи jQuery UI плагина Resizable делаем возможным ручное изменение ширины блока before. Подключение плагина осуществляется следующим образом:

 

$(".before").resizable({handles:"e", maxWidth:$("#wrap").width()-10});

 

где параметр handles указывает на направление, в котором может изменяться размер.

 

Помимо этого так же делаем возможным замену изображений для просмотра, сопровождающуюся анимацией. Для замены создаем два списка с миниатюрами: в одном миниатюры с изображениями «до», во втором «после». При нажатии на миниатюру из любого списка происходит серия из трех анимаций, с той лишь разницей, что от списка, в котором размещена миниатюра, зависит последовательность первых двух анимаций.

 

Первые две анимации записаны в следующих функциях:

 

function setBefore(src, first){
if(!first)
var k = $(".before").width() / $("#wrap").width();
else var k = 1;

$(".before").animate({width: "0%"}, 1000*k, function(){
// после скрытия блока
// происходит замена изображения
$(".before").children("img").attr("src", src);
});

return true;
}

function setAfter(src, first){
if(!first)
var k = $(".before").width() / $("#wrap").width();
else var k = 0;

$(".before").animate({width: "100%"}, 1000 - 1000*k, function(){
// после скрытия блока
// происходит замена изображения
$(".after").children("img").attr("src", src);
});

return true;
}

 

 

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

Так же, если функция запущенна второй, использовать ширину блока для расчета значения переменной k будет не верно, поскольку вторая функция будет запущенна еще до того, как завершится первая анимация, а это значит, что текущая ширина будет отличаться от той, с которой начнется вторая анимация. По этому, для определения очередности функции используется параметр first, У которого значение «true» будет в том случае, если функция запущенна второй по счету.

 

Теперь рассмотрим события при нажатии на миниатюры. Код этих событий приведен ниже:

 

$("#before li").on("click", function(event){
var before = $(this);
var after = $("#after li").eq($(this).index());

var srcBefore = before.children("img").attr("src");
var srcAfter = after.children("img").attr("src");

setAfter(srcAfter, setBefore(srcBefore));

$(".before").animate({width: "50%"}, 500, function(){
$("#before li").removeClass("active");
$("#after li").removeClass("active");

before.addClass("active");
after.addClass("active");

$(this).clearQueue();
});              
});

$("#after li").on("click", function(event){
var after = $(this);
var before = $("#before li").eq($(this).index());

var srcAfter = after.children("img").attr("src");
var srcBefore = before.children("img").attr("src");

setBefore(srcBefore, setAfter(srcAfter));

$(".before").animate({width: "50%"}, 500, function(){
$("#before li").removeClass("active");
$("#after li").removeClass("active");

after.addClass("active");
before.addClass("active");

$(this).clearQueue();
});    
});

 

 

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

 

На этом наш урок окончен. Благодарю за проявленное внимание!