Удобный перетаскиваемый слайдер для быстрого сравнения двух изображений на основе CSS3 и jQuery.
Когда вы создаете страницу продукта, есть несколько эффективных решений UX, которые можно использовать, чтобы пользователь «почувствовал» продукт. Ползунок для сравнения изображений - один из таких. Если вы посмотрите на страницу продукта Sony Ultra HD TV (sony.co.uk/electronics/tv/t/televisions), они используют этот подход, чтобы подчеркнуть разницу между их разрешением экрана и стандартным. Google использует его, чтобы показать, насколько крутым является фильтр Google+ Фото (google.com/photos/about).
Изображение предоставлено: unsplash.com.
Погрузимся в код;)
Создание структуры
Мы использовали элемент figure
, чтобы обернуть наше исходное изображение, измененное изображение и ручку слайдера:
<figure class="cd-image-container">
<img src="img/img-original.jpg" alt="Original Image">
<span class="cd-image-label" data-type="original">Original</span>
<div class="cd-resize-img"> <!-- the resizable image on top -->
<img src="img/img-modified.jpg" alt="Modified Image">
<span class="cd-image-label" data-type="modified">Modified</span>
</div>
<span class="cd-handle"></span> <!-- slider handle -->
</figure> <!-- cd-image-container -->
Добавление стиля
Исходное изображение используется для придания правильных размеров его контейнеру .cd-image-container
измененное изображение вставляется в изображение div.cd-resize
. Этот элемент устанавливается в position: absolute
над контейнером .cd-image-container
, и его ширина изменяется при перетаскивании элемента .cd-handle
(с использованием jQuery), чтобы показать / скрыть измененное изображение.
Ширина .cd-resize-image
изначально установлена на 0, а затем изменяется на 50%, когда она входит в область просмотра, с использованием класса .is-visible
, который добавляется в контейнер .cd-image-container
(с помощью jQuery). Мы также определили анимацию cd-bounce-in
для создания эффекта отскока.
Таким образом, анимация начнется только тогда, когда .cd-image-container
виден внутри области просмотра.
.cd-resize-img {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 0;
overflow: hidden;
/* Force Hardware Acceleration in WebKit */
transform: translateZ(0);
backface-visibility: hidden;
}
.is-visible .cd-resize-img {
width: 50%;
/* bounce in animation of the modified image */
animation: cd-bounce-in 0.7s;
}
@keyframes cd-bounce-in {
0% {
width: 0;
}
60% {
width: 55%;
}
100% {
width: 50%;
}
}
Обработка событий
Чтобы реализовать функциональность слайдера, мы определили функцию drags ()
, чтобы сделать элемент .cd-handle
перетаскиваемым (кредит CSS-Tricks - css-tricks.com/snippets/jquery/draggable-without-jquery-ui).
Когда мышь нажимается на элемент .cd-handle
и перемещается, мы обновляем левое значение .cd-handle
в соответствии с текущим положением мыши (мы добавили ограничение, чтобы ограничить перемещение внутри его родительского .cd-image-container
) и соответственно измените ширину div.cd-image-size
.
Чтобы добавить поддержку мобильных устройств, мы использовали jQuery mobile (в частности, события vmouse
, которые имитируют события мыши на сенсорном устройстве).
В качестве последнего эффекта, когда элемент .cd-image-container
входит в область просмотра, мы добавляем класс .is-visible
для анимации его дочерних элементов.
jQuery(document).ready(function($){
//function to check if the .cd-image-container is in the viewport here
// ...
//make the .cd-handle element draggable and modify .cd-resize-img width according to its position
$('.cd-image-container').each(function(){
var actual = $(this);
drags(actual.find('.cd-handle'), actual.find('.cd-resize-img'), actual);
});
//function to upadate images label visibility here
// ...
});
//draggable funtionality - credits to http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/
function drags(dragElement, resizeElement, container) {
dragElement.on("mousedown vmousedown", function(e) {
dragElement.addClass('draggable');
resizeElement.addClass('resizable');
var dragWidth = dragElement.outerWidth(),
xPosition = dragElement.offset().left + dragWidth - e.pageX,
containerOffset = container.offset().left,
containerWidth = container.outerWidth(),
minLeft = containerOffset + 10,
maxLeft = containerOffset + containerWidth - dragWidth - 10;
dragElement.parents().on("mousemove vmousemove", function(e) {
leftValue = e.pageX + xPosition - dragWidth;
//constrain the draggable element to move inside its container
if(leftValue < minLeft ) {
leftValue = minLeft;
} else if ( leftValue > maxLeft) {
leftValue = maxLeft;
}
widthValue = (leftValue + dragWidth/2 - containerOffset)*100/containerWidth+'%';
$('.draggable').css('left', widthValue).on("mouseup vmouseup", function() {
$(this).removeClass('draggable');
resizeElement.removeClass('resizable');
});
$('.resizable').css('width', widthValue);
//function to upadate images label visibility here
// ...
}).on("mouseup vmouseup", function(e){
dragElement.removeClass('draggable');
resizeElement.removeClass('resizable');
});
e.preventDefault();
}).on("mouseup vmouseup", function(e) {
dragElement.removeClass('draggable');
resizeElement.removeClass('resizable');
});
})
Ссылка на твиттер автора - twitter.com/romano_cla.