Данный слайдер накладывает две фотографии друг на друга и заменяет их движением мыши.

Ранее уже была заметка с похожим слайдером: splitpic.js

Отличаются они тем, что этот скрипт работает по клику мышки, а не по ее движению, как splitpic.js

Пример:

Функцию animateTo("значение") (о ней ниже) можно использовать для перемещения ползунка в нужное место и использовать на кнопках или в тексте. Например:

Когда мы лазали зимой в горах, нам хотелось лета (на лето нужно кликнуть)

HTML:

Стрелочки сделаны шрифтом Font Awesome

CSS:

JS:

  • Подключаем jQuery (если не подключено ранее)
  • Подключаем jQuery UI для вашей версии jQuery с взаимодействием Draggable или полную. Для jQuery 1.7+ можно использовать эту.
  • Подключаем приведенный ниже код

Если нет желания использовать jQuery UI, который обеспечивает перетаскивание ползунка мышкой, можно его не подключать. В этом случае слайдер будет меняться только по клику на нем мышки. Для этого нужно удалить код:

Для перемещения ползунка в нужное место используется функция animateTo("значение")

Смотрите также:

Оригинальный слайдер на jQuery, который листает карточки по кругу в одну сторону

jQuery/Zepto плагин Cloud 9 Carousel для создания 3D-карусели изображений или блоков

Адаптивный 3D слайдер-карусель с 3-мя видимыми фотографиями

Добавить комментарий:

Ваш комментарий отправлен!

Комментарии:

  • Станислав:

    Здравствуйте! Подскажите, как с фильтрами совместить? <div class="sl-container">
    Я отсюда: https://atuin.ru/blog/filtr-dlya-fotografij-na-webgl
    Пробовал вот так:

    <div class="sl-container">
    <div class="view view-after">
    <canvas id="image-filter-canvas"></canvas>
    </div>
    <div class="view view-before">
    <img src="/img/3d/1.jpg"/>
    </div>
    <div class="dragme"><div class="dr-circle"><i class="fa fa-arrows-h" aria-hidden="true"></i></div></div>
    </div>
    не выходит)

    Ответить
    • Alexander:

      Дайте ссылку на результат

      Ответить
      • Станислав:

        Всё хорошо. Не знаю, что мне померещилось спросонья... Но я думал что-то сделал не так я. Наверное не совсем проснулся, сразу за ноут и на Ваш сайт. Спасибо за Ваши труды! Всё просто супер на Вашем сайте! С праздником !

        Ответить
  • Олег Матвеев:

    Понадобилось давече наложить один список на другой (смысл такой же как с картинками) на мобильном разрешении, а на дектопе контейнеры списков были друг на против друга. По другому никак иначе смысл перечней терялся. Вдохновился данным подходом, но jquery-ui даже в урезанном и минифицированном виде оказалась великовата. Кроме того, исользовать все нужно было только на одной странице сайта. В итого, родилось следующее -- все то же самое, но без jquery

    Для понимания приведу разметку: (стили кому нужно напишите), идея проста -- дектоп два контейнера внутри одного на гридах, на мобилка -- контейнеры накладываются друг на друга абсолютом, в принципе как и тут.
    [code]
    <div class="paradigm__lists">
    <ul class="paradigm__list paradigm__list--black view-after">
    <li>Some first text</li>
    </ul>
    <ul class="paradigm__list paradigm__list--grey view-before">
    <li>Some second text</li>
    </ul>
    <div class="dragme-line"><div class="dr-circle"></div></div>
    </div>
    [/code]
    [code]
    document.addEventListener('DOMContentLoaded', () => {
    const dragMe = document.querySelector(".dragme-line");
    const container = document.querySelector(".paradigm__lists");
    const viewAfter = document.querySelector(".view-after");
    function init() {
    if (window.innerWidth < 768) {
    let isDragging = false;
    let offsetX = 0;
    dragMe.addEventListener("mousedown", (event) => {
    isDragging = true;
    offsetX = event.clientX - dragMe.offsetLeft;
    });
    window.addEventListener("mousemove", (event) => {
    if (!isDragging) return;
    const x = event.clientX - offsetX - container.offsetLeft;
    const boundedX = Math.max(0, Math.min(x, container.offsetWidth - dragMe.offsetWidth));
    dragMe.style.left = boundedX + "px";
    viewAfter.style.width = boundedX + 5 + "px";
    });
    window.addEventListener("mouseup", () => {
    isDragging = false;
    });
    container.addEventListener("click", (event) => {
    const eventLeft = event.pageX - container.offsetLeft - 15;
    animateTo(eventLeft);
    });
    animateTo("50%");
    function animateTo(left) {
    const targetLeft = left.toString().includes("%") ? left : left + "px";
    dragMe.style.transition = "left 0.5s linear";
    viewAfter.style.transition = "width 0.5s linear";

    dragMe.style.left = targetLeft;
    viewAfter.style.width = targetLeft;

    setTimeout(() => {
    dragMe.style.transition = "";
    viewAfter.style.transition = "";
    }, 500);
    }
    }
    }
    init();
    window.addEventListener('resize', init);
    });
    [/code]
    Потом я подумал, что будет неплохо, если слушателей не будет на разрешениях где они не нужны. Поэтому кода стало чуть больше, стоит все вынести в именованные функции и на остальных разрешениях заремувить слушатели.

    Более гуманный вариант скрипта:
    [code]
    document.addEventListener('DOMContentLoaded', () => {
    const dragMe = document.querySelector(".dragme-line");
    const container = document.querySelector(".paradigm__lists");
    const viewAfter = document.querySelector(".view-after");
    let isDragging = false;
    let offsetX = 0;
    function init() {
    if (window.innerWidth < 768) {
    dragMe.addEventListener("mousedown", dragStart);
    window.addEventListener("mousemove", dragging);
    window.addEventListener("mouseup", dragEnd);
    container.addEventListener("click", containerClick);
    animateTo("50%");
    } else {
    dragMe.removeEventListener("mousedown", dragStart);
    window.removeEventListener("mousemove", dragging);
    window.removeEventListener("mouseup", dragEnd);
    container.removeEventListener("click", containerClick);
    dragMe.style.left = "";
    viewAfter.style.width = "";
    }
    }
    function dragStart(event) {
    isDragging = true;
    offsetX = event.clientX - dragMe.offsetLeft;
    }
    function dragging(event) {
    if (!isDragging) return;
    const x = event.clientX - offsetX - container.offsetLeft;
    const boundedX = Math.max(0, Math.min(x, container.offsetWidth - dragMe.offsetWidth));
    dragMe.style.left = boundedX + "px";
    viewAfter.style.width = boundedX + 5 + "px";
    }
    function dragEnd() {
    isDragging = false;
    }
    function containerClick(event) {
    const eventLeft = event.pageX - container.offsetLeft - 15;
    animateTo(eventLeft);
    }
    function animateTo(left) {
    const targetLeft = left.toString().includes("%") ? left : left + "px";
    dragMe.style.transition = "left 0.5s linear";
    viewAfter.style.transition = "width 0.5s linear";
    dragMe.style.left = targetLeft;
    viewAfter.style.width = targetLeft;
    setTimeout(() => {
    dragMe.style.transition = "";
    viewAfter.style.transition = "";
    }, 500);
    }
    init();
    window.addEventListener('resize', init);
    });
    [/code]
    Возможно поможет кому то (тезке что ниже спрашивал про разные разрешения)

    Ответить
    • Олег Матвеев:

      Хотелось сохранить форматирование, но не судьба)

      Ответить
      • Alexander:

        Поправил код
        У меня тут по олдскульному они, через BBCode 🙂

        Ответить
  • Toster:

    поправил немного код, чтобы работал если на странице несколько слайдеров

    [code]
    (function($) {
    $('.sl-container').each(function() {
    var $container = $(this),
    $dragMe = $container.find('.dragme'),
    $viewAfter = $container.find('.view-after');
    $dragMe.draggable({
    containment: "parent",
    drag: function() {
    $viewAfter.css({
    width: parseFloat($(this).css('left')) + 5
    });
    }
    });
    $container.on("click", function(event) {
    var eventLeft = event.pageX - $container.offset().left - 15;
    animateTo(eventLeft, $dragMe, $viewAfter);
    });
    animateTo("50%", $dragMe, $viewAfter);
    function animateTo(_left, $dragMe, $viewAfter) {
    $dragMe.animate({
    left: _left
    }, 'slow', 'linear');
    $viewAfter.animate({
    width: _left
    }, 'slow', 'linear');
    }
    });
    })(jQuery);
    [/code]

    и чтобы размеры изображений подгонялись под блок

    [code]
    function adjustImageWidth() {
    (function($) {
    $('.sl-container').each(function() {
    var $viewBefore = $(this);
    var width = $viewBefore.width();
    var height = $('.view-before').height();
    $viewBefore.find('.view-before img').css('width', width);
    $viewBefore.find('.view-after img').css('width', width);
    $('.sl-container').css('height', height);
    });
    })(jQuery);
    }
    [/code]

    Ответить
  • Kirа:

    "Подключаем jQuery"
    Это как сделать?
    И вообще куда коды вставлять в какое место. Можно поподробнее

    Ответить
    • Alexander:

      Никак не соберусь написать помощь по установке...
      Подключается как и любой скрипт, а как остальное я даже не знаю как в 2х словах написать..
      Напишите в ТГ или ВК, попробую подсказать.

      Ответить
      • Kirа:

        Да хотя бы на примере пустого сайта.
        Скачать то то (такие то файлы)
        положить в папки такие то
        в файле таком то прописать то то
        в файл таком то прописать то то
        А лучше просто архивчик пустого сайта с одной страницей и этим скриптом

        Ответить
  • Шайлтан вор:

    Класно, спасибо сворую на совй веб сайт

    Ответить
  • Олег:

    А как сделать, чтобы ползунок работал и в мобильной версии? Это возможно?

    Ответить
    • Alexander:

      Смотрите [i]jQuery UI Draggable [/i]

      Ответить
      • Олег:

        Погуглил) Мало что понял)

        Ответить
  • Ростислав:

    С помощью какой команды нужно включить jQuery?

    Ответить
    • Alexander:

      Если не подключена, то [url="https://jquery.com/download/"]отсюда[/url]:

      Ответить
  • Kiso:

    Как добавить два и больше таких слайдера на 1 страницу ? и что бы при этом каждый слайдер работал независимо от других, сейчас если добавить 2 таких на 1 страницу то при смещении одного смещается и другой

    Ответить
    • Nick:

      Добавить 2 скрипта, 2 html блока с разными названиями и в скриптах соответственно

      Ответить