Handling gestures
Handling gestures in React Native Reanimated is done effectively using a
combination of react-native-reanimated and react-native-gesture-handler.
Step-by-Step Guide
-
Import Necessary Libraries
First, import the necessary hooks and components from both libraries.
import React from 'react';
import { View } from 'react-native';
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated, {
useAnimatedGestureHandler,
useSharedValue,
useAnimatedStyle,
} from 'react-native-reanimated'; -
Initialize Shared Values
Shared values are necessary to store and manipulate the animated state. For gesture-based animations, typically they will hold information related to position or transformation.
const translateX = useSharedValue(0);
const translateY = useSharedValue(0); -
Create Gesture Handlers
Use
useAnimatedGestureHandlerto define how your app should respond to gestures. This function provides a way to handle gesture-related data directly on the UI thread, minimizing the delay and improving responsiveness.const gestureHandler = useAnimatedGestureHandler({
onStart: (event, context) => {
context.startX = translateX.value;
context.startY = translateY.value;
},
onActive: (event, context) => {
translateX.value = context.startX + event.translationX;
translateY.value = context.startY + event.translationY;
},
onEnd: () => {
// Optionally handle gesture end event
},
}); -
Define Animated Styles
Use
useAnimatedStyleto link animated values to component styles to modify their appearance or position when gestures occur.const animatedStyle = useAnimatedStyle(() => {
return {
transform: [
{ translateX: translateX.value },
{ translateY: translateY.value },
],
};
}); -
Apply Gesture and Animation to Components
Wrap your target component with the
PanGestureHandlerand attach thegestureHandler, while also applying theanimatedStyle.return (
<PanGestureHandler onGestureEvent={gestureHandler}>
<Animated.View
style={[
{ width: 100, height: 100, backgroundColor: 'blue' },
animatedStyle,
]}
/>
</PanGestureHandler>
);
PanResponder
PanResponder provides full control over multiple touches. You can track and
manage gestureState.numberActiveTouches to handle multi-touch gestures like
pinch-to-zoom or rotation.
The gesture responder system in React Native is a low-level interface for handling touch interactions.
-
PanResponder wraps these handlers and provides:
-
A native
eventobject: Contains the raw event details (e.g., touch positions, timestamps, etc.). -
A
gestureStateobject.
gestureState is an object passed to many of the gesture handler callbacks
(e.g., onPanResponderMove, onPanResponderRelease) that contains detailed
information about the current state of the user’s gesture. It provides a range
of data points about touch behavior, such as velocity, distance, and the number
of active touches.
onPanResponderMove: (event, gestureState) => {};
Exapmle1
const ExampleComponent = () => {
const panResponder = React.useRef(
PanResponder.create({
// Ask to be the responder:
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
onPanResponderGrant: (evt, gestureState) => {
// The gesture has started. Show visual feedback so the user knows
// what is happening!
// gestureState.d{x,y} will be set to zero now
},
onPanResponderMove: (evt, gestureState) => {
// The most recent move distance is gestureState.move{X,Y}
// The accumulated gesture distance since becoming responder is
// gestureState.d{x,y}
},
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => {
// The user has released all touches while this view is the
// responder. This typically means a gesture has succeeded
},
onPanResponderTerminate: (evt, gestureState) => {
// Another component has become the responder, so this gesture
// should be cancelled
},
onShouldBlockNativeResponder: (evt, gestureState) => {
// Returns whether this component should block native components from becoming the JS
// responder. Returns true by default. Is currently only supported on android.
return true;
},
})
).current;
return <View {...panResponder.panHandlers} />;
};
Additional Tips
-
Combine Gestures: With
react-native-gesture-handler, you can use multiple gesture handlers (e.g.,TapGestureHandler,PinchGestureHandler) and define combinational gestures like dragging and zooming. -
State Management: Store contextual data (e.g., starting positions, velocities) to handle transitions from gesture-active to gesture-end states effectively.
-
Performance Considerations: As gesture handlers and animations run on the UI thread, they are optimized for responsiveness and can handle complex interactions smoothly.