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

Dragged items don't stay with mouse when zoomed in or out #638

Closed
KevinMusgrave opened this issue Feb 28, 2022 · 3 comments
Closed

Dragged items don't stay with mouse when zoomed in or out #638

KevinMusgrave opened this issue Feb 28, 2022 · 3 comments

Comments

@KevinMusgrave
Copy link

KevinMusgrave commented Feb 28, 2022

I'm using dnd-kit within react-flow, which provides a zoomable map environment.

At the default zoom level, dragging works fine. When zoomed in, the dragged item moves more than the mouse pointer. When zoomed out, the dragged item moves less than the mouse pointer.

Here's a sandbox where you can reproduce the issue: https://codesandbox.io/s/dnd-kit-react-flow-tcfed8

And here's a gif to illustrate:
brave_UswXKzaRQs

Any suggestions for how to fix this? Would react-flow's internal transform state (pan and zoom values) be useful in this case?

@efossvold
Copy link

efossvold commented Apr 12, 2022

I solved it by using a modifier.

Hook to create the modifier (takes zoom/scale as an arg):

  export const useDragWithZoomModifier =
  (zoom: number): import('@dnd-kit/core').Modifier =>
  args => {
    const { transform } = args
    return {
      ...transform,
      x: transform.x / zoom,
      y: transform.y / zoom,
    }
  }

Then apply the modifier in the DndContext:

  ...
  const zoom = useZoom() // your own implementation to get zoom
  const transformer = useDragWithZoomModifier(zoom)

  useEffect(() => {
    setCanvasOffset([canvas.x, canvas.y])
  }, [canvas.x, canvas.y])

  return (
    <DndContext modifiers={[transformer]}>
   ...

@KevinMusgrave
Copy link
Author

Thanks @efossvold that works! The only problem is that the other elements not being dragged don't seem to get this modifier applied. So the element being dragged follows the mouse now, but the other items getting re-arranged are still moving as if we're at the original zoom level.

@KevinMusgrave
Copy link
Author

KevinMusgrave commented May 21, 2022

This worked (with useSortable: https://docs.dndkit.com/presets/sortable/usesortable#usage)

  function transformWithZoom(transform) {
    if (transform) {
      return {
        ...transform,
        x: transform.x / zoom,
        y: transform.y / zoom,
      };
    }
    return transform;
  }

  const { attributes, listeners, setNodeRef, transform, transition } = useSortable({id});

  const scaledTransform = transformWithZoom(transform);

  const style = {
    transform: CSS.Transform.toString(scaledTransform),
    transition,
  };

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