I'm using react-native-reanimated v 1.9 together with react-native-gesture-handler to drag an element on the screen, I need to be able to reset the element to the previous position after the user press the "UNDO" button.
After Initializing some animated values:
this.X = new Value();
this.Y = new Value();
const offsetX = new Value();
const offsetY = new Value();
....this.handlePan function get the pan events from here:
<PanGestureHandler
ref={this.panRef}
enabled={this.panGestureHandlerEnabler}
onGestureEvent={this.handlePan}
onHandlerStateChange={this.handlePan}>
<Animated.View>
.......
</Animated.View>
</PanGestureHandler>
from this.handlePan the events are mapped to x and y, I can then use the react-native-reanimated call() method to extract some animated values at the end of any pan movement and make them available for the function recordNewState():
this.handlePan = event([
{
nativeEvent: ({
translationX: x,
translationY: y,
absoluteY: Y,
absoluteX: X,
state,
}) =>
block([
set(this.X, add(x, offsetX)),
set(this.Y, add(y, offsetY)),
cond(eq(state, State.END), [
set(offsetX, add(offsetX, x)),
set(offsetY, add(offsetY, y)),
call([this.X, this.Y], (finalXY) => {
recordNewState({
action: 'XY',
value: {X: x, Y: y},
});
}),
]),
]),
},
{useNativeDriver: true},
]);
The function recordNewState() basically build up an array of animated values, that are made available for the undo() function:
this.undo = () => {
if (lastRecordedState.length > 1) {
const undoAction =
lastRecordedState[lastRecordedState.length - 1];
switch (undoAction.action) {
case 'XY':
block([
offsetX.setValue(sub(offsetX, undoAction.value.X)),
offsetY.setValue(sub(offsetY, undoAction.value.Y)),
]);
break;
default:
break;
}
}
};
Here I check for the latest animated value (undoAction.action), in the switch statement, if it's an XY I translate the item subtracting the latest animated values. With
block([
offsetX.setValue(sub(offsetX, undoAction.value.X)),
offsetY.setValue(sub(offsetY, undoAction.value.Y)),
]);
the item doesn't move back to the previous position and the call() method get called again adding another animated value to the array.