JSFiddle - React, Tailwind, and code Playground

Scrollbar Snapping

by skibulk

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<div id="workzone"></div>
<div id="scroller"></div>

CSS

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

#workzone {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: black;
}

JavaScript

console.clear();

var workzone = document.getElementById("workzone");
var scroller = document.getElementById("scroller");

var scrollSteps = 10;
scroller.style.height = (scrollSteps * 300) + "px";

var scrollTime = 0;
var scrollCurrentPos = 0;
var scrollCurrentStep = 0;

window.addEventListener("scroll", function(event) {

	// Debounce
  var ts = Date.now();

  if (ts > scrollTime + 250) {
    scrollTime = ts;
    
	  var scrollStepSize = document.documentElement.scrollHeight / scrollSteps;
    if (window.scrollY > scrollCurrentPos) {
      // Scroll Down
      scrollCurrentStep = Math.min(scrollCurrentStep + 1, scrollSteps);
      scrollCurrentPos = scrollCurrentStep * scrollStepSize;
      window.scrollTo(0, scrollCurrentPos);
    } else if (window.scrollY < scrollCurrentPos) {
      // Scroll Up
      scrollCurrentStep = Math.max(scrollCurrentStep - 1, 0);
      scrollCurrentPos = scrollCurrentStep * scrollStepSize;
      window.scrollTo(0, scrollCurrentPos);
    }
	}
  
  /*
  var ts = Date.now();

  if (ts > scrollTime + 250) {
    scrollTime = ts;
    var docH = document.documentElement.scrollHeight;
    var scrollStepDist = docH / scrollSteps;

    var position = Math.round((window.scrollY / docH) * scrollSteps);

    if (window.scrollY > scrollStartPos) {
      // Scroll Down
      if (--position >= 0) ;
      window.scrollTo(((position * scrollSteps) / scrollSteps) * docH);
    } else {
      // Scroll Up
      if (++position < scrollSteps) ;
    }

    scrollStartPos = window.scrollY;
    workzone.style.opacity = position / scrollSteps;
    scrollPosition = position;
  }
  */
});