-
-
Notifications
You must be signed in to change notification settings - Fork 616
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
feat: pass activatorEvent to modifiers and add snapCenterToCursor modifier #334
feat: pass activatorEvent to modifiers and add snapCenterToCursor modifier #334
Conversation
🦋 Changeset detectedLatest commit: 89eaec3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 4 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @trentmwillis, thanks for taking the time to open a PR and add an example modifier of how this would be used, overall this is looking really good 💯
Is there any reason why the snapCenterToCursor
modifier couldn't be made to work with touch events as well? You could probably use the getEventCoordinates helper which works for both touch and mouse events, though you may need to move it to @dnd-kit/utilities
to share it with @dnd-kit/modifiers
Only reason was that I didn't know how to idiomatically get the coordinates for touch events. I'll update the modifier to use that helper! |
c3dd21b
to
876c36f
Compare
Updated to support Touch as well. Two notes:
|
Hi, would like to know how can i use this modifier? Will this eventually be added into the library? Thanks. |
52287b1
to
c41aa09
Compare
c41aa09
to
89eaec3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thanks for your contribution 🙏
Hey! So happy to see this feature getting worked on and accepted quickly. I the snapCenterToCursor modifier works as expected in a minimal Draggable example, but when I try to use it in the vertical sort example like this:
Instead of centering, the overlay just appears at a consistent offset from the cursor. The offset appears to be the offset from the corner of the draggables bounding box to the center of it for reference the DraggerCount element:
I've tried tweaking the DraggerCount down to something more minimal with the same effect. Am I doing something wrong? Since the spacing is consistent I can definitely hack together a solution the gets me a mouse-centered overlay, but I thought I'd ask if there was a less smelly approach before going that route. Thanks! The library is great! |
took me a bit to figure out, but in case anyone finds this, the issue was that my little red dot was in the upper left of the invisible overlay that was centering correctly, so wrapping the my DraggerCount with
centered the component inside the overlay and now it works exactly as expected. Thanks again |
@clauderic I See this is in master, any idea when master will get published to npm? |
@VFC-elindgren you can install |
@trentmwillis Were you ever able to figure out how to update the collision detection so that it worked with the center-snapped overlay? I've found that a temporary solution is using the Thanks for creating this modifier! It's been super useful in my latest project. |
@levikline, did you find any solution for making the center snapped DragOverlay compatible with |
@atonyma7 Yes! I used the // Update the target to account for snapping to center
target = { ...target };
target.top = pointerCoordinates.y - target.height / 2;
target.left = pointerCoordinates.x - target.width / 2; If you want a full example of writing a custom collision detection algorithm, DND Kit has a good page on it: In my case, I ended up developing an entirely new collision algorithm for my app, but you could copy over the rectIntersect code and this should still work (I think). And if not, that should hopefully give you an idea of how to account for the center offset. Hope that helps! |
DndKit documentation leaves a lot to be desired, there is no documentation on how to use custom collision detection algorithms. I'm not sure what your post is referring to @levikline, there is no "target" related to collision detection. Anyway, for folks looking for how to snap the drag overlay center to the cursor, and to make sure the updated collision rectangle works properly, here's the complete example. import { snapCenterToCursor } from '@dnd-kit/modifiers';
import {
CollisionDetection, DndContext, DragOverlay, rectIntersection
} from '@dnd-kit/core';
const fixCursorSnapOffset: CollisionDetection = (args) => {
// Bail out if keyboard activated
if (!args.pointerCoordinates) {
return rectIntersection(args);
}
const { x, y } = args.pointerCoordinates;
const { width, height } = args.collisionRect;
const updated = {
...args,
// The collision rectangle is broken when using snapCenterToCursor. Reset
// the collision rectangle based on pointer location and overlay size.
collisionRect: {
width,
height,
bottom: y + height / 2,
left: x - width / 2,
right: x + width / 2,
top: y - height / 2,
},
};
return rectIntersection(updated);
};
const Component = () => {
return (
<DndContext
collisionDetection={fixCursorSnapOffset}
>
{/* ... */}
<DragOverlay modifiers={[snapCenterToCursor]}>
<div>
Your overlay
</div>
</DragOverlay>
</DndContext>
);
}; |
Fixes #122 as described in #122 (comment). I also added a new modifier,
snapCenterToCursor
which should help folks that encounter similar use cases in the future.Here's a short demo video of the modifier in action:
dndkit-center-cursor.mp4
Note: This doesn't solve the issue of needing to resize the dragged node's rect used in collision detection (as described in #122 (comment)), but I am looking into that as well.