Add a way to trigger the drag start programatically
I'm trying to create a draggable element that's dragged after a certain delay pressing into it and inside a certain distance from the pointer down event.
There currently doesn't seem to be a way to implement this: if I disable the draggable, when enabling it after the delay is done, the draggable doesn't start dragging (because the disabled property exists the onDragStart early internally and doesn't even start tracking the state).
If I try to let the draggable enabled but set the position to the initial position on the onDrag handler, the element jumps back an forth between the internal draggable's position and the initial position I want it to be.
Is this solvable in some way? Maybe calling something to imperatively start the internal state when I want?
I have plans to add a delay option. That will require some amount of touching/pressing before dragging begins. Would that satisfy your needs?
The problem with solving it with a delay prop is that other cases like starting the drag only after the pointer moved a certain amount from the position it was press in are still not possible. The best way I can think of would be to make the drag activate when the active property is set to true even if the cursor is pressed, and starting from the spot the cursor is when the active property changes. So:
- press on the draggable when the
activeproperty isfalse. - move the pointer -> nothing happens.
- after some time (or some distance or whatever), we set the
activeproperty totrue. - move the pointer -> the draggable moves as if we had just pressed the pointer in the frame the
activeproperty was set totrue.
Another idea would be to have an imperative call to start the drag when we want it to.
Hi @santiagopuentep now that v2.0 is very close and you have requested it, I'll be straight: I don't really understand the API design you want.
Can you suggest some rough code examples of how this would be configurable?
Hi @santiagopuentep now that v2.0 is very close and you have requested it, I'll be straight: I don't really understand the API design you want.
Can you suggest some rough code examples of how this would be configurable?
I think that adding a new property called deadzone (an object with x and y properties) (appart from the delay property) could solve the other common use case of not starting drag after the cursor moved a certain distance from the pointerdown event. Deadzone similar to the the deadzone of controller joysticks.
It wouldn't be a general solution for all cases where we want to control when the component starts the drag (maybe some other event in the app), but at least most cases would be covered.
deadzone could be a nice name.
But I find your idea of a generic solution more appealing.
I am thinking it could maybe resemble this:
start: ({ shadowOffsetX, shadowOffsetY }) => boolean
It gives you offsetX and offsetY. This is how much the component would have moved, but it didn't. Then based on it you can return true at some point, and then the dragging properly begins. The shadowOffsetX and shadowOffsetY will be reset and ignored. You won't be able to control this function once it becomes true.
Would that be a better solution to your answer?
That sounds great! Good idea, I think that might be a complete solution 👌
@PuruVJ Do you have any programmed dates on when this is going to be added? We really need to transition to this library but we can't until this feature is there because of how our app works. Maybe I can help?
Hi! Sorry for the delay, I kinda got busy with life and other more pressing projects for a while. I can't promise when this would be released. If you think you can make a PR, I will be happy merging it ASAP :)
Awesome. Tomorrow I'll try to do those changes.
I'm trying to run the project. I did npm install and npm run compile but it's failing with this error: NX Could not find ".modules.yaml" at .... I couldn't find anyting in Google and this is the first time I use NX. Do you mind helping me to run the project? I'm running on Windows.
I use pnpm here. Try pnpm install
I have the changes complete. I managed to do the delay feature and the deadzone by letting the user return true from the onDrag callback to block the dragging. If the user returns nothing or false the drag works as usual. This way anyone can implement the feature they want however they want.
I also did some other improvements like the pointermove and pointerup events being added only when the pointer is down, instead of being permanently added and running, which is a big performance improvement.
I want to do a PR but I don't know how to run the project. If I run the react example it only shows two sliders. If I run the docs I get this error:
Failed to load url @astrojs/markdown-remark (resolved id: @astrojs/markdown-remark) in /home/santiagopuentep/neodrag-fork/docs/astro.config.ts
Could you please help me with that?
Hey man!
I test things out by going to packages/svelte/demo folder and running pnpm dev in that, while having pnpm compile:watch in packages/svelte running at all times.
If you're not familiar with svelte, you can use demo folders of other frameworks too, every single folder has a demo folder. Just remember to run pnpm compile of that framework before you run the demo server
I ended up completely changing the library to match what we need in our project, but I have a few changes that could help. I'll create issues for them.
This problem I solved by creating an onBeforeDrag callback that's run before every onDrag and if it returns true, the drag is blocked. This way the onBeforeDrag receives all the values necessary to calculate the deadzone or the delay of the drag start.
That was the best solution I could find in case you want to implement it.