0

I've got a script that lets you drag around a box called "draggable-container." There are also a couple of other things on the screen: a "window" and a footer. I'm wondering how I can make sure that when you're dragging the "draggable-container," you can't drag it over the "window" or the footer.

For example, if you start dragging the box and then try to move it over the "window" or the footer, I want it to just stop moving. How can I make this happen?

My code:

// appDrag.js

const draggableContainer = document.getElementById("draggable-container");
let isDragging = false;
let xOffset, yOffset;

draggableContainer.addEventListener("mousedown", (event) => {
  isDragging = true;
  xOffset = event.clientX - draggableContainer.getBoundingClientRect().left;
  yOffset = event.clientY - draggableContainer.getBoundingClientRect().top;

  // Add the "dragging" class to the entire container when dragging starts
  draggableContainer.classList.add("dragging");
});

document.addEventListener("mousemove", (event) => {
  if (isDragging) {
    event.preventDefault();
    draggableContainer.style.left = event.clientX - xOffset + "px";
    draggableContainer.style.top = event.clientY - yOffset + "px";
  }
});

document.addEventListener("mouseup", () => {
  isDragging = false;

  // Remove the "dragging" class when dragging ends
  draggableContainer.classList.remove("dragging");
});

I have tried implementing boundary checks, etc, but they either just don't work, or just stop draggable-container from working.

Babytron
  • 1
  • 1
  • Does this answer your question? [How to move and resize DIVs in a parent DIV container without overflowing?](https://stackoverflow.com/questions/76531761/how-to-move-and-resize-divs-in-a-parent-div-container-without-overflowing) – Alexander Nenashev Aug 24 '23 at 08:53
  • A bit similar, but not quite. – Babytron Aug 24 '23 at 19:43

2 Answers2

0

To prevent draggableContainer from moving over another square element, you can check to make sure that the two elements would not overlap before moving them.

document.addEventListener("mousemove", (event) => {
  if (isDragging) {
    const obstacle = /* an element you don't want to overlap with */;

    // The position of the top left corner of the draggable box
    const goalX = event.clientX - xOffset + "px";
    const goalY = event.clientY - yOffset + "px";

    // The size of the draggable box
    const draggableWidth = draggableContainer.getBoundingClientRect().width;
    const draggableHeight = draggableContainer.getBoundingClientRect().height;

    // The position of the top left corner of the obstacle
    const obstacleX = obstacle.getBoundingClientRect().top;
    const obstacleY = obstacle.getBoundingClientRect().left;

    // The size of the obstacle
    const obstacleWidth = obstacle.getBoundingClientRect().width;
    const obstacleHeight = obstacle.getBoundingClientRect().height;

    // If the two elements overlap
    // See https://stackoverflow.com/questions/12066870
    const rectsOverlap = !(goalX + draggableWidth < obstacleX || 
      goalX > obstacleX + obstacleWidth || 
      goalY + draggableHeight < obstacleY || 
      goalY > obstacleY + obstacleHeight);

    // If the obstacle and the place where the draggable box would be
    // if it is successfully moved overlap, don't move the box.
    if (!rectsOverlap) {
      event.preventDefault();
      draggableContainer.style.left = event.clientX - xOffset + "px";
      draggableContainer.style.top = event.clientY - yOffset + "px";
    }
  }
});
I'mAUserNow
  • 135
  • 6
  • Is there a way to do it for regular divs (with multiple elements inside the div)? I tried using this and it did not work, I might just be overthinking – Babytron Aug 24 '23 at 07:53
0

It sounds like you want to restrict the movement of the "draggable-container" so that it cannot be dragged over the "window" or the footer elements. To achieve this, you can add boundary checks in your code to prevent the container from being dragged outside the desired areas.

Here's how you can modify your existing code to achieve this:

// appDrag.js

const draggableContainer = document.getElementById("draggable-container");
const windowElement = document.getElementById("window"); // Replace with your window element's ID
const footerElement = document.getElementById("footer"); // Replace with your footer element's ID

let isDragging = false;
let xOffset, yOffset;

draggableContainer.addEventListener("mousedown", (event) => {
  isDragging = true;
  xOffset = event.clientX - draggableContainer.getBoundingClientRect().left;
  yOffset = event.clientY - draggableContainer.getBoundingClientRect().top;

  // Add the "dragging" class to the entire container when dragging starts
  draggableContainer.classList.add("dragging");
});

document.addEventListener("mousemove", (event) => {
  if (isDragging) {
    event.preventDefault();

    // Calculate the new position
    const newX = event.clientX - xOffset;
    const newY = event.clientY - yOffset;

    // Get the boundaries of the window and footer
    const windowRect = windowElement.getBoundingClientRect();
    const footerRect = footerElement.getBoundingClientRect();

    // Check if the new position is within the boundaries
    if (
      newX >= windowRect.left &&
      newX + draggableContainer.offsetWidth <= windowRect.right &&
      newY >= windowRect.top &&
      newY + draggableContainer.offsetHeight <= footerRect.top
    ) {
      // Update the position only if it's within the boundaries
      draggableContainer.style.left = newX + "px";
      draggableContainer.style.top = newY + "px";
    }
  }
});

document.addEventListener("mouseup", () => {
  isDragging = false;

  // Remove the "dragging" class when dragging ends
  draggableContainer.classList.remove("dragging");
});

In this code, the position of the "draggable-container" is only updated if the new position is within the boundaries defined by the "window" and the area above the "footer". This prevents the container from being dragged over these elements. Make sure to replace "window" and "footer" with the actual IDs of your window and footer elements.

Remember that this solution assumes that the "window" and footer elements are not dynamically resized or moved, as the boundary checks are based on the initial positions of these elements. It could be further changed, but for the basic solution, it is enough.

Atzuki
  • 627
  • 1
  • 5
  • 16
  • I already said: I have tried implementing boundary checks, etc, but they either just don't work, or just stop draggable-container from working. – Babytron Aug 24 '23 at 19:35