BetterTyped / react-zoom-pan-pinch

🖼 React library to support easy zoom, pan, pinch on various html dom elements like <img> and <div>
MIT License
1.48k stars 268 forks source link

Unable to use drag and drop functionality inside of TransformWrapper #460

Open llong opened 6 months ago

llong commented 6 months ago

Describe the bug I'm trying to use react-zoom-pan-pinch withreact-dnd but items nested within the are not responding to drag events. I've tried disabling panning to see if that helps but I am still unable to drag items. Items are responding to other mouse events such as mouseOver, click, mouseDown, mouseUp etc. I'm also seeing the canDrag() value from react-dnd for the draggable item returning as true. The native onDrag prop on elements within the are also not triggering an event.

Expected behavior I would like to be able to able to both zoom, pan and drag and drop items within the

Desktop (please complete the following information):

BenjaminBecic commented 5 months ago

Here is Workaround if u want to use it with react-dnd:

1. declare a state variable which deactivates the TransformWrapper:

const [transformWrapperDisabled, setTransformWrapperDisabled] = useState(false)

2. use the variable on the TransformWrapper component:

<TransformWrapper disabled={transformWrapperDisabled}>

3. use these event listener on the Draggable Element to enable and disable state:

  1. onMouseDown -> which sets the state to true
  2. onDragEnd -> which sets the state to false
  3. onMouseUp -> which sets the state to false

    For example, if this div is the root of your draggable component, it could look like this: <div ref={drop} style={styles} onMouseDown={**callbackToSetStateToTrue**} onDragEnd={**callbackToSetStateToFalse**} onMouseUp={**callbackToSetStateToFalse**}>...</div>

One more thing I had to struggle with: If you use a CustomDragLayer for previewing the dragged component, you might encounter offset issues. This is because the TransformWrapper uses translate, which confines the DragLayer to the width and height of the TransformWrapper. This limitation does not apply to monitor.getInitialSourceClientOffset from the useDragLayer hook. Therefore, you can wrap the DragLayerComponent with a Portal component (I use mui/react). It likely also works with createPortal() from react-dom.