Cравнения двух изображений на основе CSS3 и jQuery

Удобный перетаскиваемый слайдер для быстрого сравнения двух изображений на основе 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.


Top

🔖 Выбор по тегам ×

💌 Написать сообщение ×

Все поля обязательны для заполнения!