Comments (14)
Thanks for the assistance, the second sandbox turned out to be very informative after all. Your explanations are very clear, and much appreciated.
I would suggest adding that explanation about returning temp
to the Frequently asked questions
that already exists in the readme. It's very useful knowledge.
For whoever comes here after me, here is a sandbox to a working split-pane solution build on react-spring
and react-use-gesture
. Without rerenders, and only a single animated element. If you need more than 2 columns, I would recommend to nest this component and not to add 2 draggers in a single 'splitPane' component.
https://codesandbox.io/s/react-use-gesture-72v26
from use-gesture.
Just so you know, I've finally changed temp
to memo
, as I think of it as a sort of cached value. temp
is still there if you need it with the same value as memo
:)
from use-gesture.
Sure, happy to help. I’ll ask the creator of this lib @drcmda what he thinks about a new name for temp!
from use-gesture.
Figured it out, new docs explain it: https://use-gesture.netlify.com/docs/options
from use-gesture.
Hey @smeijer, thanks for taking the time to capture the gif and creating the sandbox.
I suspect the bug is only due to z-index
messing up things. Here is a working example (at least it works with me):
https://codesandbox.io/s/react-use-gesture-07q16
I've also corrected some code: here is your original code commented with the problems highlighted.
const [[left, right], set] = useState([250, 250]);
const bind = useGesture({
onDrag: ({ initial: [x], delta: [dx] }) => {
/* Here x will be the initial x-axis position of the MOUSE.
* What you want instead is the initial position of the red handle!
* It might have worked fine in your case if your element is in the top left corner of the screen
* but it wouldn't if it was positioned elsewhere.
* The solution is to use the `temp` argument like in the sandbox above */
const nextLeft = x + dx;
const nextRight = left + right - nextLeft;
set([nextLeft, nextRight]);
},
});
The other problem here is that you're re-rendering your component on every drag update. You could use for example the react-spring
library to prevent useless renders when animating. Here is a reworked example, optimized (I've also changed the structure so only one div animates its transform attribute - since it's less costly than animating width
).
https://codesandbox.io/s/react-use-gesture-k4bwv
from use-gesture.
Thanks for the fast response. I'll try that first sandbox later tomorrow, but it seems to make sense.
The second sandbox wouldn't work for me though. As the elements left and right from the dragger will contain content, and thereby both need to be resized.
*edit, one quick question. You're returning temp
from the onDrag, is it required? Does it do something?
from use-gesture.
Whatever works best, but in any case make sure you’re not re-rendering your whole component on each drag frame. You will probably need to have several animated.div
nodes but I think you can still work it out with only one spring value.
Yes it is required by design to return temp. Essentially temp is a gesture state attribute that is undefined when the gesture starts, but then takes the return value of the handler function.
In our case, we want temp to hold the original value of x when the gesture starts so that it becomes our point of reference when adding the delta. So we set temp to the value of x when temp is undefined.
If we don’t return temp, then temp will still be undefined and in the next drag frame temp will take again the value of x, which will have updated in the meantime (therefore not being the point of reference when the gesture starts anymore).
It may sound silly but returning temp makes sure that we continue holding a reference to the initial value of temp, ie the original value of x when the gesture started.
Hope this is somehow clear.
from use-gesture.
Clever use of flex :) yeah I know that temp is yet a somewhat obscure area of this lib, there is a section dedicated to it in the read me but I agree that it doesn’t explain a lot. I also think the name doesn’t help!
from use-gesture.
Maybe naming it ref
or reference
would help? As I now understand it does pretty much the same as useRef
from react. And return reference;
or even return current;
does sound more understandable than return temp;
.
To close this chapter from my side, I created a reusable and nestable component for the SplitPane
above. Hope it might be useful for anyone:
https://codesandbox.io/s/react-use-gesture-j9v2q
Again; thanks for the fast response and explanations. Much appreciated.
from use-gesture.
I've been following this issue as it's similar to something I'm making as well, and I found a few bugs, at least for the latest versions of react-spring
and react-use-gesture
. I made a simple slider example shown below.
On versions 6.0.0 or greater of react-use-gesture
, it looks like the cursor doesn't exactly follow the mouse, when the panel is clamped to a specific value. It goes over or under the mouse:
However, on versions below 6, such as on 5.2.4, the drag handle only resizes the box while the pointer is directly underneath the drag handle:
This feels like a regression to me, but there might be good reasons, or fixes available for it, not sure.
Here's the sandbox:
from use-gesture.
Hey @satvikpendem thanks for taking the time to report the issue. Having a sandbox and gifs is indeed super helpful 👍
In this case though, the answer is pretty trivial: 6.x deprecated temp
, and delta
was relabeled movement
(in 6.x delta is xy - previous
to match common usage).
Here is the updated sandbox: https://codesandbox.io/s/react-use-gesture-simple-id76z
I've commented out another implementation that uses v7 new initial
and bounds
options for your reference. Also updated react-spring to latest canary (hence size.get()
instead of size.getValue()
).
from use-gesture.
Oh thanks, looks good. This may not be entirely react-use-gesture related, but I wanted to make a draggable box, like Google Calendar where you can click and drag to resize events. If there's content inside of them, then the size of the Panel changes, so when I do
const [{ size }, set] = useSpring(() => ({ size: 300 }))
I'm not sure what to put as the initial size instead of 300. Is there a way to dynamically set the initial size
property based on the content inside an element? I know the dragging takes care of the size changes afterward.
Here's the sandbox:
https://codesandbox.io/s/react-use-gesture-simple-esw2x
from use-gesture.
It’s actually 100% react spring related. You’ll need to use a hook such as useMeasure that watches the height of the children and set your spring to its value.
from use-gesture.
I see, thanks. I'm using useGesture
, is there a way to specify the config object like you showed in the most recent sandbox within the onDrag
property? It looks like it just takes the state
. I'm trying to do something like this:
const bind = useGesture(
{
onDrag: (
// State
({ movement: [, movementY], down }) => {
console.log(movementY)
set({ size: movementY, immediate: down })
},
// Config
{
bounds: { top: minSize, bottom: maxSize },
initial: () => [0, size.get()],
rubberband: true
}
),
onHover: state => {
console.log(state)
}
}
from use-gesture.
Related Issues (20)
- Using alt+left for navigation prevents all gestures on elements with axis: 'y'
- Drag gesture: Delay setting behavior does not adhere to documentation HOT 4
- Drag + Click + filtertaps option breaks onclick listener. Drag + Click + Treshold works. HOT 1
- touch-action: pan-y prevents L shaped gestures to scroll
- onPinch breaking on control + scroll HOT 5
- Where do I import a3f from? HOT 1
- Getting the error "a3f is not defined"
- Textarea doesn't work inside gesture container HOT 4
- Documentation website is broken (in firefox) HOT 8
- Type error with @types/react >=18.2.66
- (Firefox) Click event fired on drag end
- 100ms delay between pointermove events in Android webviews? HOT 1
- [@use-gesture/vanilla] Touch event was abnormally interrupted. HOT 1
- The codesandbox example has TypeError
- Zoom pinch gestures and the from parameter
- Vanilla - Glitch during fast gestures
- Reset pinch offset, change pinch sensitivity and change unpinching behaviour
- Rotating/onWheel function only works on mobile
- state swipe is -1 for both axes even with axis restricted to y
- Swiping too hard causes the whole viewport unclickable HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from use-gesture.