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

Drag multiple objects at once #474

Open
markvital opened this issue Apr 26, 2020 · 8 comments
Open

Drag multiple objects at once #474

markvital opened this issue Apr 26, 2020 · 8 comments

Comments

@markvital
Copy link

markvital commented Apr 26, 2020

Hi,

Is it possible to drag multiple draggable instances at once?
I’m using draggable to manipulate geometric shapes. The objects are in different positions in DOM model, so I can not wrap them in one .. instance.

Here is an example of what I want to achieve:
dragAndDropMultiple
When I drag the rectangle, rounded square or triangle, all 3 should move at the same time.
I have to maintain the order in which the objects overlap while dragging (so I can't wrap all of them into one element).

It would be great to have some sort of draggableGroup attribute to assign to different draggable components. Or some way to exchange information between different draggable elements.
I know such a possibility exists in react-dnd, but it's a much complicated framework to use for me.

@devinhalladay
Copy link

+1, anyone have an existing solution for this? I'd like to avoid writing my own if something is out there…haven't found anything yet, though.

@markvital
Copy link
Author

One of the solutions would be to store some state delta with relative offset in the parent component and then pass it to children, each wrapped in Draggable component.

Here is an example: https://stackoverflow.com/a/61469976

function Canvas(props) {
  const [delta, setDelta] = useState(null); // cursor offset while dragging, {x:0, y:0}
  const [selected, setSelected] = useState([]);

  return (
      // draggable elements, each wrapped in react-draggable
      <DraggableElements delta={delta} onDrag={handleDrag}>
        //..
      </DraggableElements>
  )
}
function DraggableElements(props) {
    const {children, ...restProps } = props;
    const draggable = children.map((child, idx) => <DraggableItem key={idx} id={idx} {...restProps}>{child}</DraggableItem>);
    return(
        <>{draggable}</>
    )
}
<ReactDraggable onDrag={ (e, data) => { onDrag({x: data.x, y: data.y }, id) } }>
   <g style={delta ? {transform: `translate(${delta.x}px, ${delta.y}px)`} }>
      //...
   </g> 
</ReactDraggable>

@markvital
Copy link
Author

Unfortunately this approach doesn't work really well, because ReactDraggable permanently changes changes css properties of underlying element, so if the element will be dragged several times it will result jumps:
codepen.io/markvital/pen/vYNZXgW

It would be cool if react-draggable could work in "DragHandler" mode, when it proses mouse/touch events for drag&drop, but doesn't change DOM of elements, so the transformation could be handled onStart, onDrag, onStop calls.

@mghdmi
Copy link

mghdmi commented Feb 21, 2021

anyone found a solution for this?

@STRML
Copy link
Collaborator

STRML commented Feb 21, 2021 via email

@moklick
Copy link

moklick commented Feb 21, 2021

We implemented this exact use case in our react-flow library. It looks something like this:

  1. wrap all draggable elements with DraggableCore (you always need to store all positions of your elements and pass it to the DraggableCore wrapper)
  2. append the onDrag handler for all elements (and remember which ones are selected and their positions)
  3. when the user drags an element you can use data.deltaX and data.deltaY of the onDrag handler and add it to all positions of the selected elements

Hope it helps :)

@braniubojni
Copy link

Hi @moklick can you provide some demo or sample?

@siva-morpho
Copy link

Is there a solution for this yet?

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

7 participants