How to fix Div element "jump" on drag?

Viewed 122

The dragging works but the bug is that when I drag the element somehow "jumps" and does not flow with the mouse. See it in the code. Don't worry about removing event listeners, I will add them as soon as this works.
I have an issue on a draggable "div" element. I've searched many answers before I posted this question but nothing seems to be the solution(or maybe I am not understanding the problem really well).
Thank you!

const hotspot = document.getElementsByClassName("hotspot")[0];
const container = document.getElementsByClassName("container")[0];
let containerRect = container.getBoundingClientRect();
let hsRect = hotspot.getBoundingClientRect();

let relMouse = { x: 0, y: 0 };
let windowMouse = { x: 0, y: 0 };
let isUserIntercating = false;

const handlePointerUp = (e) => {
  isUserIntercating = false;
};

const handlePointerDown = (e) => {
  isUserIntercating = true;
  hsRect = hotspot.getBoundingClientRect();
  relMouse = { x: e.pageX - hsRect.x, y: e.pageY - hsRect.y };

  window.addEventListener("pointerup", handlePointerUp, false);
};

const handlePointerMove = (e) => {
  hsRect = hotspot.getBoundingClientRect();
  containerRect = container.getBoundingClientRect();
  windowMouse = { x: e.clientX - relMouse.x, y: e.clientY - relMouse.y };
};
const update = (t) => {
  requestAnimationFrame(update);
  if (isUserIntercating) {
    hotspot.style.transform = `translate(${
      windowMouse.x - containerRect.x
    }px,0px)`;
  }
};
update();
hotspot.addEventListener("pointerdown", handlePointerDown, false);
window.addEventListener("pointermove", handlePointerMove, false);
body {
  font-family: sans-serif;
  margin: 0;
}
.container {
  padding: 0;
  margin: 50px;
  max-width: 600px;
  min-height: 600px;
  background-color: blanchedalmond;
}

.hotspot {
  /* position: absolute; */
  background-color: aqua;
  /* transform: translate(100px, 100px); */
  min-height: 100px;
  max-width: 100px;
  z-index: 200;
}
<!DOCTYPE html>
<html>
  <head>
    
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div class="container">
      <div class="hotspot"></div>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

1 Answers

Try like this:

const hotspot = document.getElementsByClassName("hotspot")[0];
const container = document.getElementsByClassName("container")[0];
let containerRect = container.getBoundingClientRect();
let hsRect = hotspot.getBoundingClientRect();

let relMouse = { x: 0, y: 0 };
let windowMouse = { x: 0, y: 0 };
let isUserIntercating = false;

const handlePointerUp = (e) => {
  isUserIntercating = false;
};

const handlePointerDown = (e) => {
  isUserIntercating = true;
  hsRect = hotspot.getBoundingClientRect();
  relMouse = { x: e.pageX - hsRect.x, y: e.pageY - hsRect.y };

  window.addEventListener("pointerup", handlePointerUp, false);
};

const handlePointerMove = (e) => {
  hsRect = hotspot.getBoundingClientRect();
  containerRect = container.getBoundingClientRect();
  windowMouse = { x: e.clientX - relMouse.x, y: e.clientY - relMouse.y };
  requestAnimationFrame(update);
};
const update = (t) => {
  if (isUserIntercating) {
    hotspot.style.transform = `translate(${
      windowMouse.x - containerRect.x
    }px,0px)`;
  }
};
hotspot.addEventListener("pointerdown", handlePointerDown, false);
window.addEventListener("pointermove", handlePointerMove, false);
body {
  font-family: sans-serif;
  margin: 0;
}
.container {
  padding: 0;
  margin: 50px;
  max-width: 600px;
  min-height: 600px;
  background-color: blanchedalmond;
}

.hotspot {
  /* position: absolute; */
  background-color: aqua;
  /* transform: translate(100px, 100px); */
  min-height: 100px;
  max-width: 100px;
  z-index: 200;
}
<!DOCTYPE html>
<html>
  <head>
    
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>

  <body>
    <div class="container">
      <div class="hotspot"></div>
    </div>
    <script src="src/index.js"></script>
  </body>
</html>

The issue seemed to be that the update function kept calling itself all the time, which is not really ideal. The update should only be called in the handlePointerMove function (only change the hotspot position when the mouse moves).

Related