Reputation: 13803
I am trying to create an animated drag and drop feature, like this: http://moduscreate.com/animated_drag_and_drop_with_react_native/
I want to change it so that when the user starts the touch, the object moves upwards so that it is no longer hidden under their finger. I want this movement to be animated, but I also want to track the panning gesture during the animation.
Right now I have the animation working, as long as the user doesn't move their finger. I am using this code to animate the object up when the touch starts:
onPanResponderStart: (e, gesture) => {
Animated.spring(
this.state.pan,
{
...animationConstants,
toValue: { x: 0, y: -70 },
}
).start((status) => {
// This part ensures that the offset and value are
// set correctly after the animation.
this.state.pan.y.setOffset(-70);
this.state.pan.y.setValue(0);
});
},
But as soon as they move their finger, it cancels the animation and jumps to the top. I am using this code for onPanResponderMove
:
onPanResponderMove: Animated.event([null, {
dx: this.state.pan.x,
dy: this.state.pan.y
}]),
I want the animation to continue, even while the user is moving their finger.
How could I change the code so that I am animating the "offset", instead of the "value"? I think I could solve this problem if Animated.spring
had the option to use toOffset: {x: ..., y: ...}
, as well as to toValue
. But I don't think it has that, and I'm not sure how I should emulate this.
Upvotes: 3
Views: 2852
Reputation: 13803
I figured something out. I'm not sure about performance, but it seems to work fine.
I set up a separate Animated.Value
to animate the offset. I just added a callback using addListener
, which calls setOffset
to animate the value.
constructor(props){
super(props);
this.state = {
pan: new Animated.ValueXY(),
offset: new Animated.Value(0)
};
this.state.offset.addListener((value) => {
this.state.pan.y.setOffset(value.value);
});
this.panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderStart: (e, gesture) => {
Animated.spring(
this.state.offset,
{ toValue: -70 }
).start();
},
onPanResponderMove: Animated.event([null, {
dx: this.state.pan.x,
dy: this.state.pan.y
}]),
onPanResponderRelease: (e, gesture) => {
Animated.spring(
this.state.pan,
{
toValue: { x: 0, y: 0 }
}
).start();
Animated.spring(
this.state.offset,
{ toValue: 0 }
).start();
}
});
}
Upvotes: 1