Задать вопрос

Где найти такой слайдер?

Всем привет стоит задача вот такуэ карусельку сделать, обчно работаю с swiperно тут заткнулся ника не могу ее нормально работать заставить,
68ce64584da45559733339.jpeg
может кто подскажет готовую, когда то видел на Owl Carousel
не могу найти
  • Вопрос задан
  • 167 просмотров
Подписаться 1 Простой 3 комментария
Решения вопроса 1
ashfedor
@ashfedor Автор вопроса
Набросал свой скрипт, конечно нужно дорабатывать, но как основа пойдет
стили и разметку думаю не сложно понять
<div class="home-cases__slider home-cases__stack" style="height: 675px;">
  <div class="home-cases__slide ">
    <div class="home-cases__slider-item ">
      карточка
    </div>
  </div>
  <div class="home-cases__slide ">

    <div class="home-cases__slider-item ">
      карточка
    </div>
  </div>
  <div class="home-cases__slide ">

    <div class="home-cases__slider-item ">
      карточка
    </div>
  </div>
</div>
<script>
    (function () {
      function initStack(root) {
        const stack  = root.querySelector('.home-cases__stack');
        if (!stack) return;
        const slides = Array.from(stack.querySelectorAll('.home-cases__slide'));
        if (!slides.length) return;

        const scope  = root.closest('.home-cases') || document;
        const prevBt = scope.querySelector('.home-cases__slider-prev');
        const nextBt = scope.querySelector('.home-cases__slider-next');
        const surface = root.querySelector('.home-cases__viewport') || stack;

        let i = 0;

        function a11y() {
          slides.forEach((sl) => {
            const hidden = !sl.classList.contains('is-active') &&
              !sl.classList.contains('is-prev-1') &&
              !sl.classList.contains('is-prev-2');
            sl.setAttribute('aria-hidden', hidden ? 'true' : 'false');
            sl.querySelectorAll('a,button,input,select,textarea,[tabindex]')
              .forEach(el => el.tabIndex = hidden ? -1 : 0);
          });
        }

        function setHeight() {
          stack.style.height = slides[i].offsetHeight + 'px';
        }

        function render() {
          const n  = slides.length;
          const n1 = (i + 1) % n;
          const n2 = (i + 2) % n;

          slides.forEach((sl, idx) => {
            sl.classList.remove('is-active','is-prev-1','is-prev-2','is-hidden');
            if (idx === i)       sl.classList.add('is-active');
            else if (idx === n1) sl.classList.add('is-prev-1');
            else if (n > 2 && idx === n2) sl.classList.add('is-prev-2');
            else sl.classList.add('is-hidden');
          });

          setHeight();
          a11y();

          // якщо використовуємо ResizeObserver — перевішуємо на новий активний
          ro && (ro.disconnect(), ro.observe(slides[i]));
        }

        // висота по зміні контенту — без «стрибків»
        const ro = new ResizeObserver(setHeight);
        ro.observe(slides[i]);

        // кнопки
        nextBt && nextBt.addEventListener('click', () => { i = (i + 1) % slides.length; render(); });
        prevBt && prevBt.addEventListener('click', () => { i = (i - 1 + slides.length) % slides.length; render(); });

        // === свайп / drag ===
        (function attachSwipe() {
          const HAS_POINTER = 'PointerEvent' in window;
          const THRESHOLD = 40;     // пікселів для спрацьовування
          const TOLERANCE = 10;     // мертва зона
          let startX = 0, startY = 0;
          let isDown = false, isDragging = false, isScrolling = false;
          let swiped = false;

          // не починати drag із клікабельних елементів
          function isInteractive(el) {
            return !!el.closest('a,button,input,select,textarea,label,[data-no-drag]');
          }

          function getPoint(e){
            if (e.touches && e.touches[0]) return { x: e.touches[0].clientX, y: e.touches[0].clientY };
            return { x: e.clientX, y: e.clientY };
          }

          function down(e){
            if (isInteractive(e.target)) return; // даємо клікнути
            const p = getPoint(e);
            startX = p.x; startY = p.y;
            isDown = true; isDragging = false; isScrolling = false;
            surface.classList.add('is-grabbing');
            // pointer capture (де є)
            if (e.pointerId != null && surface.setPointerCapture) {
              try { surface.setPointerCapture(e.pointerId); } catch(_) {}
            }
          }

          function move(e){
            if (!isDown) return;
            const p = getPoint(e);
            const dx = p.x - startX;
            const dy = p.y - startY;

            if (!isDragging) {
              if (Math.abs(dx) < TOLERANCE && Math.abs(dy) < TOLERANCE) return;

              if (Math.abs(dy) > Math.abs(dx)) { // вертикальний жест => скрол
                isScrolling = true;
                up(e);
                return;
              }
              isDragging = true;
            }

            if (isDragging) {
              // блокуємо нативний горизонтальний скрол під час свайпу
              if (e.cancelable) e.preventDefault();
            }
          }

          function up(e){
            if (!isDown) return;
            surface.classList.remove('is-grabbing');

            if (!isScrolling && isDragging) {
              const p = getPoint(e);
              const dx = p.x - startX;
              if (Math.abs(dx) > THRESHOLD) {
                if (dx < 0) i = (i + 1) % slides.length;           // ліворуч => наступний
                else        i = (i - 1 + slides.length) % slides.length; // праворуч => попередній
                render();
                swiped = true;
              }
            }

            isDown = isDragging = isScrolling = false;
          }

          // блокуємо кліки після свайпу
          root.addEventListener('click', function(e){
            if (swiped) { e.preventDefault(); e.stopPropagation(); swiped = false; }
          }, true);

          // Події з урахуванням підтримки PointerEvent
          if (HAS_POINTER) {
            surface.addEventListener('pointerdown', down);
            surface.addEventListener('pointermove', move, { passive: false });
            surface.addEventListener('pointerup', up);
            surface.addEventListener('pointercancel', up);
            surface.addEventListener('pointerleave', up);
          } else {
            // fallback для старого iOS Safari
            surface.addEventListener('touchstart', down, { passive: true });
            surface.addEventListener('touchmove', move, { passive: false });
            surface.addEventListener('touchend', up);
            surface.addEventListener('mousedown', down);
            window.addEventListener('mousemove', move);
            window.addEventListener('mouseup', up);
          }
        })();

        window.addEventListener('resize', setHeight, { passive: true });
        render();
      }

      document.querySelectorAll('.home-cases').forEach(initStack);
    })();
  </script>
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы