JSFiddle - React, Tailwind, and code Playground

by Leon

HTML

<!-- Stats box -->
<div class="output-container">
  <p id="xyPos">Move the mouse</p>
  <p id="mouseScroll">You can scroll too</p>
</div>

<!-- Main program -->
<div id="outerContainer">
  <div id="container">
    <div id="item"></div>
  </div>
</div>

CSS

body,
html {
  margin: 0;
  padding: 0;
  background-color: pink;
}

body {
  background-color: pink;
}

.output-container {
  position: fixed;
  color: white;
  font-size: 18px;
  padding-right: 10px;
  right: 0;
  text-align: right;
}

#container {
  width: 100%;
  height: 800px;
  margin: 0;
  margin-top: 50px;
  padding: 0;
  background-color: #333;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  touch-action: none;
}

#item {
  width: 50px;
  height: 50px;
  background-color: rgb(245, 230, 99);
  border: 10px solid rgba(136, 136, 136, .5);
  border-radius: 50%;
  touch-action: none;
  user-select: none;
}

#item:active {
  background-color: rgba(168, 218, 220, 1.00);
}

#item:hover {
  cursor: pointer;
}

JavaScript

// show stats
let xyPosOutput = document.querySelector("#xyPos");
let mouseScrollOutput = document.querySelector("#mouseScroll");
let xPos;
let yPos;

// --------------------------------------------------

const dragItem = document.querySelector("#item");
const container = document.querySelector("#container");

let active = false;
let currentX;
let currentY;
let scrollY = 0;
let initialX;
let initialY;
let xOffset = 0;
let yOffset = 0;

// output stats
const xyPos = (e) => {
  xPos = e.clientX;
  yPos = e.clientY;
  xyPosOutput.innerHTML = `x: ${xPos}<br>y: ${yPos}`;
}
container.addEventListener("mousemove", xyPos, false);

// Update scroll position 
const mouseScroll = (e) => {
  scrollY = window.scrollY;
  mouseScrollOutput.innerHTML = `y: ${scrollY}`;
}
window.addEventListener('scroll', mouseScroll, false);

// -------------------------------------------------------

container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);

function dragStart(e) {
  initialX = e.clientX - xOffset;
  initialY = (e.clientY - yOffset) + scrollY;

  if (e.target === dragItem) {
    active = true;
  }
  console.log("dragStart - Triggered");
}

function dragEnd(e) {
  initialX = currentX;
  initialY = currentY;

  active = false;
}

function drag(e) {
  if (active) {

    e.preventDefault();

    // pointer action
    currentX = e.clientX - initialX;
    currentY = (e.clientY - initialY) + scrollY;


    xOffset = currentX;
    yOffset = currentY;

    setTranslate(currentX, currentY, dragItem);
    console.log("drag() - Triggered");
  }
}

function setTranslate(xPos, yPos, el) {
  //el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
  el.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`;
}