How to make draggable remember its location in React Native

I will learn about animation and panresponder apis in the native response. After Animated Drag and Drop Using React Native and Source

I want to expand the example so that you can drag the circle without having to reset. Currently, the code animates the circle back to the center of the screen and relies on the values โ€‹โ€‹of the dX / dY transmitters.

My best guess: I need to change something in onPanResponderMove

  onPanResponderMove: Animated.event([null, { dx: this.state.pan.x, dy: this.state.pan.y, }]), 

What do I need to change in the source, so if I comment on the onPanResponderRelease logic, onPanResponderRelease circle correctly drag the screen?

getTranslateTransform() ?

+5
source share
3 answers

The logic in onPanResponderRelease makes it so that if draggable is not in the dropzone when it is released, then reset returns to 0,0 ( these are the lines calling it ).

Removing this logic is not all that you should do. You must set the offset and reset the value of this.state.pan to onPanResponderRelease . To do this, you need to track the value.

In componentDidMount add the following:

 this.currentPanValue = {x: 0, y: 0}; this.panListener = this.state.pan.addListener((value) => this.currentPanValue = value); 

Then in componentWillUnmount :

 this.state.pan.removeListener(this.panListener); 

Now that you have the current value, you simply add it to the PanResponder:

 onPanResponderRelease: (e, gestureState) => { this.state.pan.setOffset({x: this.currentPanValue.x, y: this.currentPanValue.y}); this.state.pan.setValue({x: 0, y: 0}); }, 

It seems more complicated than it really is. Basically, you just set the offset from 0/0, and then set the value to 0/0 so that when you move it again after releasing it, it doesn't go back to 0/0 before moving back to where your finger is. It also ensures that you have a current position ... which you will probably need at some point.

+4
source

Another way is to track the current offset and continue to add it to the pan. Therefore, declare this in the constructor currentPanValue : {x: 0, y: 0},

And change onPanResponderRelease to the following:

 onPanResponderRelease : (e, gesture) => { this.state.currentPanValue.x += this.state.pan.x._value; this.state.currentPanValue.y += this.state.pan.y._value; this.state.pan.setOffset({x: this.state.currentPanValue.x, y: this.state.currentPanValue.y}); this.state.pan.setValue({x: 0, y: 0}); } 

If you want to get the final coordinates, you should get it using this.state.currentPanValue

+3
source

In fact, the only thing you need to change is the onPanResponderRelease function. What you are doing now is applying the delta gesture movement to the starting position of the component. What you want to do is apply it to the position at the end of the last gesture. Therefore, you somehow need to maintain the offset. AnimatedValueXY.setOffset for salvation!

 onPanResponderRelease : (e, gesture) => { if(this.isDropZone(gesture)){ this.setState({ showDraggable : false }); }else{ this.state.pan.setOffset({ x: this.state.pan.x._offset + e.dx, y: this.state.pan.y._offset + e.dy, }) this.state.pan.setValue({x: 0, y: 0}) } 

I use the _offset internal variable here because I can find a way to access it through the API. You can also simply track the offset manually. I have not tested this code yet, but you get the point.

0
source

Source: https://habr.com/ru/post/1240979/


All Articles