Fix draggable direction when parent is rotated#3589
Open
mattgperry wants to merge 2 commits intomainfrom
Open
Conversation
When a draggable element is inside a rotated parent motion component, the drag direction was incorrect because page-space pointer offsets were applied directly as CSS translateX/translateY, which operate in the parent's local coordinate system. The fix computes the inverse of the accumulated parent transform matrix (rotation + scale) from the visual element tree at drag start, then transforms the page-space offset into the parent's local coordinate system before applying it. This ensures the element follows the cursor correctly regardless of ancestor rotation or scale. Fixes #3320 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Greptile SummaryThis PR fixes a bug where draggable elements moved opposite to the cursor when inside a rotated parent. The fix computes the inverse of the accumulated parent transform matrix (rotation + scale) and applies it to pointer offsets, correctly translating page-space coordinates into the parent's local coordinate system. Key Changes:
Implementation Quality:
The fix is well-scoped to 2D transforms (rotate/rotateZ and scale), which covers the common use cases. More complex scenarios like 3D transforms or skew are not addressed but are acceptable limitations for this targeted bugfix. Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant PanSession
participant DragControls as VisualElementDragControls
participant Matrix as calcInverseParentMatrix
participant MotionValue
User->>PanSession: Pointer down (drag start)
PanSession->>DragControls: onStart(event, info)
DragControls->>Matrix: Calculate inverse matrix
Matrix->>Matrix: Walk up parent tree
Matrix->>Matrix: Accumulate transforms (rotate, scale)
Matrix->>Matrix: Invert 2×2 matrix
Matrix-->>DragControls: Return inverse matrix (cached)
User->>PanSession: Pointer move (dragging)
PanSession->>DragControls: onMove(event, info)
Note over DragControls: info.offset in page space
DragControls->>DragControls: applyInverseTransform(offset)
Note over DragControls: Transform to parent's local space
DragControls->>DragControls: updateAxis("x", correctedOffset)
DragControls->>DragControls: updateAxis("y", correctedOffset)
DragControls->>MotionValue: Set translateX/Y
Note over MotionValue: Values now in correct coordinate system
User->>PanSession: Pointer up (drag end)
PanSession->>DragControls: onStop(event, info)
DragControls->>DragControls: applyInverseTransform(velocity)
DragControls->>DragControls: startAnimation(correctedVelocity)
Note over DragControls: Momentum also uses corrected coordinates
Last reviewed commit: 47f84c0 |
Recompute the inverse parent matrix on every pointer move so the correction stays accurate when the parent is animating (e.g. a continuously rotating container). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
motioncomponent (e.g.,<motion.div style={{ rotate: 180 }}>), the drag direction was inverted — the element moved opposite to the cursortranslateX/translateY, which operate in the parent's local coordinate system. A 180° rotation inverts both axes, so positive page-space offsets produce negative visual movementTest plan
drag-rotated-parent.ts) that verifies element follows cursor when parent hasrotate: 180yarn buildpassesyarn testpasses (91 suites, 760 tests)Fixes #3320
🤖 Generated with Claude Code