motiondivision / motiondivision/motion
[BUG] `snapToCursor` accumulates position drift on repeated drags with initial coordinates
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 33.7k
- Forks
- 1.4k
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 14
Description
Description
We discovered this while testing React Motion parity in @humanspeak/svelte-motion. After noticing repeated snap-to-cursor drift in our Svelte implementation, we independently reproduced the same behavior using public React Motion APIs.
When an element has initial x/y coordinates, the first controlled drag snaps correctly. Subsequent starts progressively offset the element from the pointer.
Reproduction
The example uses:
const controls = useDragControls();
<button
onPointerDown={(event) =>
controls.start(event, { snapToCursor: true })
}
>
Start Initial Drag
</button>
<motion.div
drag
dragControls={controls}
dragListener={false}
dragMomentum={false}
initial={{ x: 100, y: 40 }}
/>
Steps to reproduce
- Press and hold Start Initial Drag.
- Move the pointer approximately 150 pixels right and 50 pixels down.
- Release.
- Repeat the same gesture from the button several times.
Expected behavior
Every pointerdown should center the element beneath the pointer, regardless of its previous position. Repeating the same gesture should produce the same final position.
Actual behavior
Subsequent starts accumulate an offset. The element drifts upward and away from the pointer instead of centering beneath it.
Versions
motion,framer-motion,motion-dom: 13.2.0react,react-dom: 19.1.1- Reproduced in Chromium.
Investigation
The snap calculation appears to combine a stored projection layout measurement with the changing current motion value, causing the correction to accumulate across sessions.
This may be related to #3445, which addressed first-drag snapping with initial coordinates. We haven’t bisected the history to establish when the repeated-start behavior was introduced.
We have a failing real-browser regression test in our Svelte repository and would be happy to contribute a focused upstream fix with browser regression coverage.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the linked StackBlitz reproduction and inspect the drag snap calculation, especially how projection layout measurements interact with current motion values. Compare the behavior with PR #3445, then reproduce the repeated-start drift and add focused browser regression coverage matching the reported gesture.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 62/100