Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collision detection #746

Open
stefann01 opened this issue Apr 4, 2024 · 1 comment
Open

Collision detection #746

stefann01 opened this issue Apr 4, 2024 · 1 comment

Comments

@stefann01
Copy link

Hi!

Is there also a collision detection inside this library so that I cannot overlap rectangles when I drag them around?

Really cool library btw.

@JEKO10
Copy link

JEKO10 commented Jul 7, 2024

No, the react-draggable library doesn't have built-in collision detection to prevent overlapping rectangles. However, you can achieve collision detection functionality using other methods. Here are two approaches:

  1. Manual Collision Detection with React:

This approach involves writing your React code to check for collisions between draggable elements:

import React, { useRef, useState } from 'react';
import Draggable from 'react-draggable';

const MyDraggable = ({ children, onDrag, ...draggableProps }) => {
  const [position, setPosition] = useState({ x: 0, y: 0 });
  const ref = useRef(null);

  const handleDrag = (event, data) => {
    const otherDraggables = [...]; // Array containing references to other draggable elements

    // Check for collision with other draggables
    const isCollidingWithOthers = otherDraggables.some(other => {
      const rectA = ref.current.getBoundingClientRect();
      const rectB = other.current.getBoundingClientRect(); // Access other draggable's ref

      return (
        rectA.left < rectB.right &&
        rectA.right > rectB.left &&
        rectA.top < rectB.bottom &&
        rectA.bottom > rectB.top
      );
    });

    if (isCollidingWithOthers) {
      // Handle collision here (e.g., prevent movement, snap to grid)
      return;
    }

    // Update draggable position if no collision
    setPosition({ x: data.x, y: data.y });
    onDrag && onDrag(event, data); // Call your custom drag function if needed
  };

  return (
    <Draggable ref={ref} onDrag={handleDrag} {...draggableProps} position={position}>
      {children}
    </Draggable>
  );
};

Usage:

const MyComponent = () => {
  const draggable1Ref = useRef(null);
  const draggable2Ref = useRef(null);
  // ... (other draggable references)

  const handleDrag1 = (event, data) => {
    handleDrag(event, data, draggable1Ref);
  };

  const handleDrag2 = (event, data) => {
    handleDrag(event, data, draggable2Ref);
  };

  // ... (other drag handlers)

  return (
    <div>
      <MyDraggable ref={draggable1Ref} onDrag={handleDrag1}>
        <div style={{ width: 100, height: 100, backgroundColor: 'red' }}>Draggable 1</div>
      </MyDraggable>
      <MyDraggable ref={draggable2Ref} onDrag={handleDrag2}>
        <div style={{ width: 100, height: 100, backgroundColor: 'blue' }}>Draggable 2</div>
      </MyDraggable>
      {/* ... (other draggables) */}
    </div>
  );
};
  1. Third-party Libraries:

Several libraries offer collision detection functionalities that can be integrated with react-draggable. Here are a few options:

-react-dnd: This popular library provides drag-and-drop functionalities, including collision detection and other advanced features.

-react-grid-layout: This library helps manage draggable elements in a grid layout, ensuring they don't overlap.
These libraries offer different functionalities and levels of complexity.

Hope this helps :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants