How do you make a slider of a trigger that is scrubbed?



  • I'm trying to make a slider that responds to the scrub. When this slider block is reached, the user should stop and cover it only with the slider after the slide ends the page. I tried to use one-page scroll, but it doesn't seem to work out there. I also tried to use gsap.

    $(".projects").onepage_scroll({
        sectionContainer: ".item-slide", 
        easing: "ease",                   
        animationTime: 700,             
        pagination: false,               
        updateURL: false,               
        beforeMove: function(index) {
    
    },  
    afterMove: function(index) {
    
    },  
    loop: false,                    
    keyboard: true,                 
    responsiveFallback: false,       
    direction: "horizontal"            
    

    });



  • Corrected the code, added the window size processor. Left comments on the code. The code has become more stable. Get as many slides as you like in any direction.

    const presenter = document.querySelector('.presenter');
    const slides = [...document.querySelectorAll('.presenter > .slide')].map((element, index) => ({
      index,
      element,
      isFirst: element.classList.contains('first'),
      isLast: element.classList.contains('last'),
      animIn: [...element.classList.values()].filter(cls => /^in-/.test(cls))[0].substr(3),
      animOut: [...element.classList.values()].filter(cls => /^out-/.test(cls))[0].substr(4),
      title: element.querySelector('h2').innerHTML,
      color: null,
      scrollPos: null,
      scrollIn: null,
      scrollOut: null,
    }));
    

    let totalScroll;

    // Распорка для скролинга
    const space = document.createElement('div');
    space.classList.add('space');
    presenter.appendChild(space);

    // Пересчитать слайды
    recalculate();

    for (let index = 0; index < slides.length; index++) {
    const slide = slides[index];
    // Разукрасим слайды
    slide.element.style.backgroundColor = randomColor();
    // Добавим в распорку слайд нужного размера
    const spaceSlide = document.createElement('div');
    spaceSlide.classList.add('slide', ['up', 'down'].includes(slide.animIn) ? 'vert' : 'horiz');
    space.appendChild(spaceSlide);
    }

    presenter.onscroll = () => reposition();

    window.onresize = () => {
    recalculate();
    reposition();
    };

    // Функция перерасчитывает положения и размеры слайдов
    function recalculate() {
    // Расчет
    totalScroll = 0;
    for (let index = 0; index < slides.length; index++) {
    const slide = slides[index];
    slide.scrollPos = totalScroll;
    totalScroll += ['up', 'down'].includes(slide.animOut)
    ? innerHeight
    : ['left', 'right'].includes(slide.animOut)
    ? innerWidth
    : innerHeight;
    }

    space.style.height = totalScroll + 'px';

    for (let index = 0; index < slides.length; index++) {
    const slide = slides[index];
    slide.element.style.top =
    slide.animIn == 'up' ? innerHeight + 'px' : slide.animIn == 'down' ? -innerHeight + 'px' : 0;
    slide.element.style.left =
    slide.animIn == 'left' ? innerWidth + 'px' : slide.animIn == 'right' ? -innerWidth + 'px' : 0;
    slide.scrollIn =
    slide.animIn == 'up' || slide.animIn == 'down'
    ? slide.scrollPos - innerHeight
    : slide.animIn == 'left' || slide.animIn == 'right'
    ? slide.scrollPos - innerWidth
    : slide.scrollPos;
    slide.scrollOut =
    slide.animOut == 'up' || slide.animOut == 'down'
    ? slide.scrollPos + innerHeight
    : slide.animOut == 'left' || slide.animOut == 'right'
    ? slide.scrollPos + innerWidth
    : slide.scrollPos;
    }
    }

    // Фнкция репозиционирует слайды при сколле
    function reposition() {
    let scrollTop = document.scrollingElement.scrollTop;
    for (let index = 0; index < slides.length; index++) {
    const slide = slides[index];
    let left, top;
    if (slide.scrollIn < scrollTop && scrollTop < slide.scrollOut) {
    // Слайд в пределах видимости
    if (scrollTop < slide.scrollPos) {
    // Следующий слайд
    [left, top] = (
    slide.animIn == 'up'
    ? [0, slide.scrollPos - scrollTop]
    : slide.animIn == 'left'
    ? [slide.scrollPos - scrollTop, 0]
    : slide.animIn == 'right'
    ? [scrollTop - slide.scrollPos, 0]
    : slide.animIn == 'down'
    ? [0, scrollTop - slide.scrollPos]
    : [0, 0]
    ).map(v => ${v}px);
    } else {
    // Предыдущий слайд
    [left, top] = (
    slide.animOut == 'up'
    ? [0, slide.scrollPos - scrollTop]
    : slide.animOut == 'left'
    ? [slide.scrollPos - scrollTop, 0]
    : slide.animOut == 'right'
    ? [scrollTop - slide.scrollPos, 0]
    : slide.animOut == 'down'
    ? [0, scrollTop - slide.scrollPos]
    : [0, 0]
    ).map(v => ${v}px);
    }
    } else {
    // Слайд вне диапазона видимости
    if (slide.scrollIn > scrollTop) {
    // Слайд еще впереди
    [left, top] = (
    slide.animIn == 'up'
    ? [0, 0 - innerHeight]
    : slide.animIn == 'left'
    ? [0 - innerWidth, 0]
    : slide.animIn == 'right'
    ? [innerWidth, 0]
    : slide.animIn == 'down'
    ? [0, innerHeight]
    : [0, 0]
    ).map(v => ${v}px);
    } else if (slide.scrollOut < scrollTop) {
    // Слайд уже позади
    [left, top] = (
    slide.animOut == 'up'
    ? [0, innerHeight]
    : slide.animOut == 'left'
    ? [innerWidth, 0]
    : slide.animOut == 'right'
    ? [0 - innerWidth, 0]
    : slide.animOut == 'down'
    ? [0, 0 - innerHeight]
    : [0, 0]
    ).map(v => ${v}px);
    }
    }
    Object.assign(slide.element.style, { left, top });
    }
    }

    presenter.querySelector('.first').style.top = 0;

    // Функция возвращает рандомный цввет
    function randomColor() {
    // Берем цвета более светлые (>128)
    const red = (128 + ~~(128 * Math.random())).toString(16);
    const grn = (128 + ~~(128 * Math.random())).toString(16);
    const blu = (128 + ~~(128 * Math.random())).toString(16);
    return #${red}${grn}${blu};
    }

    /** @format */
    html {
    scroll-snap-type: y mandatory;
    }

    • {
      box-sizing: border-box;
      }
      /* Головной элемент /
      .presenter {
      margin: 0;
      min-height: 100vh;
      scroll-snap-type: y mandatory;
      }
      /
      Слайд /
      .presenter > .slide {
      width: 100vw;
      height: 100vh;
      position: fixed;
      display: flex;
      justify-content: center;
      align-items: center;
      }
      /
      Заголовок слайда /
      .presenter > .slide h2 {
      font-size: 5em;
      color: black;
      }
      /
      Слайд в распорке /
      .presenter > .space > .slide {
      scroll-snap-align: end;
      scroll-snap-stop: normal;
      }
      /
      Вертикальное позиционирование /
      .presenter > .space > .slide.horiz {
      height: 100vw;
      }
      /
      Горизонтальное позиционирование */
      .presenter > .space > .slide.vert {
      height: 100vh;
      }
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="shortcut icon" href='data:image/svg+xml,<svg%20xmlns="http://www.w3.org/2000/svg"></svg>' />
    <link rel="stylesheet" href="./presenter.css" />
    </head>
    <body class="presenter">
    <div class="slide first in-up out-up"><h2>1</h2></div>
    <div class="slide in-up out-up"><h2>2</h2></div>
    <div class="slide in-up out-left"><h2>3</h2></div>
    <div class="slide in-left out-left"><h2>4</h2></div>
    <div class="slide in-left out-up"><h2>5</h2></div>
    <div class="slide in-up out-up"><h2>6</h2></div>
    <div class="slide in-up out-right"><h2>7</h2></div>
    <div class="slide in-right out-right"><h2>8</h2></div>
    <div class="slide in-right out-up"><h2>9</h2></div>
    <div class="slide in-up out-up"><h2>10</h2></div>
    <div class="slide in-up out-up last"><h2>11</h2></div>
    <script src="./presenter.js"></script>
    </body>
    </html>



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2