First onMouseDown event jumps because default initialClickPosition
Description
At the very first dragging interaction, the default initialClickPosition causes a jump. This jump is as large as the distance between my mouse and the default position, which is {x: 0, y: 0}. In other words, it doesn't matter where I place my cursor; the window's top-left position will jump to the cursor's exact location.
This issue occurs when I:
- start to pan within the canvas (using the mouse)
- or grab a Node to move it around.
Here is a video for demonstration:
IMPORTANT!
In the video there are jumps where the element is replaced to its starting position. It is becaues I am refreshing the browser. With this action the initialClickPosition is also resets to its default value: {x: 0, y: 0}. Other than that, when a circle appears around the cursor, it indicates a click. Those jumps are the indications of the bug.
https://github.com/user-attachments/assets/f2b63024-11f0-4e09-be8e-8a7db2a51ed4
Reproduction
I think this bug occurs because the initialClickPosition still has its default value when the first event fires. These lines are responsible for handling this event:
Inside: src/lib/containers/Graph :
```
function onMouseDown(e: MouseEvent) { if (!pannable && !(e.shiftKey || e.metaKey)) return; if (e.button === 2) return; if ($graphDOMElement) $graphDOMElement.focus();
const { clientX, clientY } = e;
$initialClickPosition = get(cursor);
if (e.shiftKey || e.metaKey) {
e.preventDefault();
selecting = true;
const { top, left } = dimensions;
anchor.y = clientY - top;
anchor.x = clientX - left;
anchor.top = top;
anchor.left = left;
if (e.shiftKey && e.metaKey) {
creating = true;
} else {
creating = false;
}
if (e.metaKey && !e.shiftKey) {
adding = true;
} else {
adding = false;
}
} else {
isMovable = true;
$selected = new Set();
$selected = $selected;
}
}
This event can be traced further, as it is where the initialClickPosition is handled. Therefore, this should be managed before the original event, so that by the time it is used, it already has the correct cursor position.
`src/lib/stores/CursorStore.ts:`
export const cursorPositionRaw = readable({ x: 0, y: 0 }, (set) => { const updateCursorPosition = (e: MouseEvent) => { set({ x: e.clientX, y: e.clientY }); };
document.addEventListener('mousemove', updateCursorPosition);
return () => {
window.removeEventListener('mousemove', updateCursorPosition);
};
});
It focuses on the event that directly interacts with the mouse, but the issue might also occur during the touch event.
### System information
Both in:
- chrome
- firefox
With Svelte 5
### Additional information
_No response_
### ๐จโ๐งโ๐ฆ Contributing
- [ ] ๐โโ๏ธ Yes, I'd love to make a PR to fix this bug!
I am experiencing the same issue in Edge. It is difficult to manually work around this. How can we contribute to an internal svelvet fix?
Right now my workaround is to issue a synthetic click on the "svelvet-wrapper" DOM element that makes the svelvet object gain focus and set the initial mouse position. It's just a temporary workaround for now but it goes something like this:
function handleCanvasMouseEnter() {
if (canvasEl && typeof canvasEl.focus === "function") {
console.log("Mouse Enters: Focusing canvas");
canvasEl.focus();
// Get bounding rectangle for coordinates
let rect;
try {
rect = canvasEl.getBoundingClientRect();
console.log("Bounding rect:", rect);
} catch (err) {
console.error("Error getting bounding rect:", err);
return;
}
const clientX = rect.left + 10; // Small offset inside canvas
const clientY = rect.top + 10;
// Dispatch synthetic mousedown event
const mouseDownEvent = new MouseEvent("mousedown", {
bubbles: true,
cancelable: true,
clientX: clientX,
clientY: clientY,
});
canvasEl.dispatchEvent(mouseDownEvent);
// Dispatch synthetic mouseup event
const mouseUpEvent = new MouseEvent("mouseup", {
bubbles: true,
cancelable: true,
clientX: clientX,
clientY: clientY,
});
canvasEl.dispatchEvent(mouseUpEvent);
console.log("Synthetic click dispatched on mount at:", {
clientX,
clientY,
});
}
}