0

I recently found this website that uses scroll snapping. I looked into it and found that CSS supports this. However, it looks like snapping happens after the user stops scrolling. The same applies with the answer to this question.

The next thing I tried was using window.scrollTo and react-scroll, but both of these weren't as smooth as the website I've linked as an example since the user could still "fight" the scrolling by scrolling in the other direction.

I want it to scroll snap when the user starts scrolling. How can I do this with CSS or JavaScript?

APixel Visuals
  • 1,508
  • 4
  • 20
  • 38
  • this seems to be what the website you linked to is using https://alvarotrigo.com/fullPage/ writing it yourself thew way you want is something I will have to test myself – Anders Kitson Apr 24 '20 at 01:28
  • @AndersKitson Fullpage looks perfect, thanks, feel free to turn this into an answer – APixel Visuals Apr 25 '20 at 00:08

2 Answers2

1

The developer you were looking at is using this js script if you ant to emulate it exactly https://alvarotrigo.com/fullPage/

Anders Kitson
  • 1,413
  • 6
  • 38
  • 98
0

If jQuery is an option, that would be the easiest solution with the best browser compatibility. You can use the "wheel" event listener to detect the direction of the scroll, and then use jQuery animate to scroll the window to the appropriate element. I've provided an example based on this GitHub repo: https://github.com/epranka/sections-slider.

(function($) {
  var selector = ".section";
  var direction;
  var $slide;
  var offsetTop;
  var $slides = $(selector);
  var currentSlide = 0;
  var isAnimating = false;

  var stopAnimation = function() {
    setTimeout(function() {
      isAnimating = false;
    }, 300);
  };

  var bottomIsReached = function($elem) {
    var rect = $elem[0].getBoundingClientRect();
    return rect.bottom <= $(window).height();
  };

  var topIsReached = function($elem) {
    var rect = $elem[0].getBoundingClientRect();
    return rect.top >= 0;
  };

  document.addEventListener(
    "wheel",
    function(event) {
      var $currentSlide = $($slides[currentSlide]);

      if (isAnimating) {
        event.preventDefault();
        return;
      }

      direction = -event.deltaY;

      if (direction < 0) {
        // next
        if (currentSlide + 1 >= $slides.length) {
          return;
        }
        if (!bottomIsReached($currentSlide)) {
          return;
        }
        event.preventDefault();
        currentSlide++;
        $slide = $($slides[currentSlide]);
        offsetTop = $slide.offset().top;
        isAnimating = true;
        $("html, body").animate({
            scrollTop: offsetTop
          },
          1000,
          stopAnimation
        );
      } else {
        // back
        if (currentSlide - 1 < 0) {
          return;
        }
        if (!topIsReached($currentSlide)) {
          return;
        }
        event.preventDefault();
        currentSlide--;
        $slide = $($slides[currentSlide]);
        offsetTop = $slide.offset().top;
        isAnimating = true;
        $("html, body").animate({
            scrollTop: offsetTop
          },
          1000,
          stopAnimation
        );
      }
    }, {
      passive: false
    }
  );
})(jQuery);
.section {
  position: relative;
  display: flex;
  height: 100vh;
}

#section1 {
  background: blue;
}

#section2 {
  background: #ff8c42;
}

#section3 {
  background: #6699cc;
}

#section4 {
  background: #00b9ae;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="section1" class="section"></div>
<div id="section2" class="section"></div>
<div id="section3" class="section"></div>
<div id="section4" class="section"></div>
Travis Wagner
  • 339
  • 3
  • 4