Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to bound the draggable div within the container

I am using react with typescript and I implemented the w3school drag div example in my react app. Now, I am trying to bound this draggable div within the boundary. Currently, my box is moving outside the container. please help how to achieve this without using any third-party library.

Here is my sandbox demo

my code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import "./styles.css";
import React, { useRef } from "react";

export default function App() {
  const dragRef = useRef<HTMLDivElement>(null);
  let pos1 = 0,
    pos2 = 0,
    pos3 = 0,
    pos4 = 0;

  const drag = (event: any) => {
    const boundingBox = dragRef.current;

    if (boundingBox) {
      event = event || window.event;
      event.preventDefault();
      pos1 = pos3 - event.clientX;
      pos2 = pos4 - event.clientY;
      pos3 = event.clientX;
      pos4 = event.clientY;
      boundingBox.style.top = boundingBox.offsetTop - pos2 + "px";
      boundingBox.style.left = boundingBox.offsetLeft - pos1 + "px";
    }
  };

  const stop = () => {
    const boundingBox = dragRef.current;
    if (boundingBox) {
      boundingBox.onmouseup = null;
      boundingBox.onmousemove = null;
    }
  };

  const start = (event: any) => {
    const box = dragRef.current;
    if (box) {
      event = event || window.event;
      event.preventDefault();
      pos3 = event.clientX;
      pos4 = event.clientY;
      box.onmouseup = stop;
      box.onmousemove = drag;
    }
  };

  return (
    <div className="App">
      <div
        ref={dragRef}
        className="draggableDiv"
        onMouseDown={start}
        onMouseMove={drag}
        onMouseUp={stop}
      ></div>
    </div>
  );
}

and the external CSS file:

.App {
  font-family: sans-serif;
  height: 350px;
  width: 400px;
  background-color: rgb(132, 190, 241);
  position: relative;
}

.draggableDiv {
  position: absolute;
  height: 40px;
  width: 40px;
  background-color: red;
  cursor: grab;
}

>Solution :

You can keep another ref to the draggable area and check if the clientX and clientY are within that range.

  1. Create another ref and attach to draggable area div.
const dragAreaRef = useRef<HTMLDivElement>(null);
...
...
  return (
    <div className="App" ref={dragAreaRef}>
      ...
    </div>
  );
  1. Update the drag function like below.
  const drag = (event: any) => {
    const boundingBox = dragRef.current;

    const {
      left,
      right,
      top,
      bottom
    } = dragAreaRef.current?.getBoundingClientRect();

    if (boundingBox) {
      event = event || window.event;
      if (
        event.clientX > left &&
        event.clientX < right &&
        event.clientY > top &&
        event.clientY < bottom
      ) {
        event.preventDefault();
        pos1 = pos3 - event.clientX;
        pos2 = pos4 - event.clientY;
        pos3 = event.clientX;
        pos4 = event.clientY;
        boundingBox.style.top = boundingBox.offsetTop - pos2 + "px";
        boundingBox.style.left = boundingBox.offsetLeft - pos1 + "px";
      }
    }
  };

Edit React Typescript (forked)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading