How to make draggable remember it's location in React Native

前端 未结 3 730
没有蜡笔的小新
没有蜡笔的小新 2021-01-05 09:40

I\'m learning about the animation and panresponder apis in react native. Following Animated Drag and Drop with React Native and the source

I want to extend the examp

相关标签:
3条回答
  • 2021-01-05 10:25

    The logic in onPanResponderRelease is making it so that if the draggable is not in the dropzone when released, it is reset back to 0,0 (these are the lines causing it).

    Removing that logic alone isn't all you should do though. You should set the offset and reset the value of this.state.pan in onPanResponderRelease. To do this you need to track the value.

    In componentDidMount, add this:

    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 just add this 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 actually is. Basically you are just setting the offset from 0/0, then setting the value to 0/0 so that when you start moving it again after having released it before, it doesn't jump back to 0/0 before jumping back to where your finger is. It also makes sure you have its current position...which you will probably need at some point anyways.

    0 讨论(0)
  • 2021-01-05 10:39

    Another way would be to track current offset and keep adding it to the pan. So declare this in the constructor currentPanValue : {x: 0, y: 0},

    And edit the 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});
                }
    

    Incase if you want the final coordinates, you should get it with this.state.currentPanValue

    0 讨论(0)
  • 2021-01-05 10:39

    Actually the only thing you need to change is the onPanResponderRelease function. What you are currently doing is applying the delta of the gesture movement to the initial position of the component. What you want to do is applying it to the position at the end of the last gesture. So you somehow need to save the offset. AnimatedValueXY.setOffset to the rescue!

    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'm using the internal _offset variable here because I could find a way to access it via the API. You can off course also just keep track of the offset manually. I didn't test this code yet, but you get the idea.

    0 讨论(0)
提交回复
热议问题