JSFiddle - React, Tailwind, and code Playground

by phloe

HTML

<div id="c">
  <ol id="t">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
  </ol>
</div>

CSS

* {
  margin: 0;
  padding: 0;
}
div {
  overflow: hidden;
}
ol {
  list-style: none;
  font-size: 0;
  white-space: nowrap;
}
li {
  width: 100%;
  display: inline-block;
  font-size: 1rem;
  white-space: normal;
  background-color: red;
  min-height: 300px;
}
li:nth-child(2) {
  background-color: orange;
}
li:nth-child(3) {
  background-color: yellow;
}
li:nth-child(4) {
  background-color: green;
}
li:nth-child(5) {
  background-color: blue;
}
li:nth-child(6) {
  background-color: purple;
}

JavaScript

var origin;
var prev;
var now;
var velocity;
var offset = 0;
var _offset = 0;
var decelFrame;
var speed;

function down (event) {
  if (speed) {
  	end();
  }
	if (!origin || speed) {
  	origin = [event.clientX, event.clientY, +new Date()];
    speed = 0;
		document.addEventListener("mousemove", move);
    document.addEventListener("mouseup", up);
  }
}

function move (event) {
	if (origin) {
  	prev = now || origin;
  	now = [event.clientX, event.clientY, +new Date()];
    setPos(prev[0] - origin[0]);
  }
}

function up () {
  document.removeEventListener("mousemove", move);
  document.removeEventListener("mouseup", up);
  if (now) {
    var frame = (now[2] - prev[2]) / 16;
    velocity = [
      (now[0] - prev[0]) * frame,
      (now[1] - prev[1]) * frame
    ];
    speed = 1;
    decelFrame = requestAnimationFrame(decel);
  }
}

const decelRate = 1;//0.99;

function decel () {
	if (speed > .01) {
  	var time = +new Date();
  	var ms = time - now[2];
    var frames = ms / 16;
    speed *= decelRate / frames;
    now[0] += velocity[0] * speed;
    now[1] += velocity[1] * speed;
    now[2] = time;
    setPos(now[0] - origin[0]);
   	decelFrame = requestAnimationFrame(decel);
  }
  else if (speed > 0) {
  	end();
  }
}

function end () {
    cancelAnimationFrame(decelFrame);
    decelFrame = null;
  	speed = 0;
  	origin = null;
  	now = null;
  	prev = null;
    velocity = null;
    offset = _offset;
}

function setPos (x) {
	_offset = offset + x;
	t.style.transform = `translateX(${_offset}px)`;
}

c.addEventListener("mousedown", down);