excalidraw icon indicating copy to clipboard operation
excalidraw copied to clipboard

Incorrect mouse position when showing Excalidraw editor inside Dialog window

Open BleedingDev opened this issue 2 years ago • 7 comments

Bug description

Mouse is incorrectly capturing the position over components (and the start of arrows etc.) when the editor is shown inside the Dialog window (I use one from https://github.com/shadcn-ui/ui).

Steps to reproduce

  1. Go to https://coursition.com/demo/excalidraw/edit
  2. Add component Excalidraw
  3. Open the editor
  4. Use the editor and see that things behave "weirdly" about the mouse position - the arrow starts in another place, and you can't edit objects (like arrows, squares etc.) at their position but your mouse needs to be a bit below and to the right.
  5. Resize the window so that the size of the Excalidraw window also changes (open DevTools => Mobile emulator => close DevTools).
  6. Everything should work correctly.

Current outcome

Position of the mouse is fixed only after the window resizes.

Expected outcome

Position of the mouse is correct all the time.

Related bugs

I reported the same thing inside Novel - https://github.com/steven-tey/novel/issues/234 but there it is even worse because the position of the mouse is not fixed when I resize the window. Seems to be related to the calculation of coordinates.

BleedingDev avatar Nov 18 '23 13:11 BleedingDev

So I went a bit more in-depth and it seems like the size of Excalidraw Window is calculated incorrectly.

Before window resize: image image

After window resize: image image

You can clearly see that the dimensions of the canvas element are now correct.

It is taken from DevTools.

BleedingDev avatar Nov 18 '23 14:11 BleedingDev

Hello ,I'm new to open source can you assign this issue to me.

mause-01 avatar Nov 19 '23 07:11 mause-01

I can't, but maintainer of the repo could. Anyways it doesn't really matter, you can try to do it without assignment. It is better to start than wait. :) @mause-01

BleedingDev avatar Nov 19 '23 18:11 BleedingDev

Hey @BleedingDev thanks for opening up this issue. Could you maybe create a sandbox where the editor is embedded inside a dialog window?

https://docs.excalidraw.com/docs/introduction/development#code-sandbox

ryan-di avatar Nov 22 '23 04:11 ryan-di

Hi @ryan-di, I will try it. :) My project is open source, so I could Link to it as well, but that is not minimal reproducible example.

BleedingDev avatar Nov 22 '23 07:11 BleedingDev

I am not able to reproduce it in Code Sandbox. :/ Can I force Excalidraw to recalculate the size without changing the window size? Because consistently fixes it.

BleedingDev avatar Nov 23 '23 14:11 BleedingDev

i'm seeing the same thing frequently, but it's hard to repro reliably.

https://github.com/user-attachments/assets/1da47b56-91b5-4c7f-ac14-a71c4b9daf28

richburdon avatar Aug 12 '24 19:08 richburdon

I can repro this issue, but it has to do with an alert that is opened then closed for me.

I created a repo to reproduce the cursor drawing being off and when you resize the window it's fixed. Like @BleedingDev mentioned, but that's only because the initial alert is now done rendering. Could there be something that collapses in your view that isn't there after the page is initially loaded? or something that is rendered only on first load?

To try my fix, clone the repro, change the .env.development var to true and it will try to render the excalidraw after the alert is dismissed. This then fixes the cursor issue.

Here is the repo, it should have all the steps in the readme to experiment with.

domshyra avatar Apr 10 '25 21:04 domshyra

I have handled this by that way

  // TODO: ExcaliDraw issue https://github.com/excalidraw/excalidraw/issues/7312
  useEffect(() => {
    if (isOpen) {
      const timerId = setTimeout(() => {
        setShouldRender(true);
      }, 200);

      return () => {
        clearTimeout(timerId);
        setShouldRender(false);
      };
    } else {
      setShouldRender(false);
    }
  }, [isOpen]);

  useEffect(() => {
    if (isOpen && shouldRender && containerRef.current) {
      const timersId = setTimeout(() => {
        if (containerRef.current) {
          window.dispatchEvent(new Event("resize"));
        }
      }, 150);

      return () => {
        clearTimeout(timersId);
      };
    }
  }, [isOpen, shouldRender]);

  return (
    <div className="bf-flex-1 bf-space-y-4 bf-overflow-auto custom-scroll bf-p-4">
      <div
        ref={containerRef}
        className="bf-w-full sm:bf-w-[70%] bf-mx-auto bf-h-[70vh] bf-relative"
      >
        {shouldRender ? (
          <Excalidraw
            initialData={initialData}
            onChange={(elements, appState, files) => {
              handleUpdate(elements, appState, files);
            }}
            theme="light"
            name={`excalidraw-${blockId}`}
          />
        ) : (
          <div className="bf-w-full bf-h-full bf-flex bf-items-center bf-justify-center bf-bg-gray-100 bf-rounded-lg">
            <div className="bf-text-gray-500">Loading editor...</div>
          </div>
        )}
      </div>
    </div>
  );
};

etozhealkhipce avatar Jun 21 '25 10:06 etozhealkhipce

Has anyone found a reliable solution to this via just container styles? I'm not trying to open it in a modal even, but I'm running in to similar issues with objects not aligning with the mouse input.

flusterIO avatar Oct 27 '25 23:10 flusterIO