Skip to content

Instantly share code, notes, and snippets.

@pytqqq
Last active February 3, 2023 08:18
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated, {
useAnimatedGestureHandler,
useAnimatedStyle,
useSharedValue,
withSpring,
} from 'react-native-reanimated';
const Snappable = (props) => {
const startingPosition = 0;
const x = useSharedValue(startingPosition);
const y = useSharedValue(startingPosition);
const animatedStyle = useAnimatedStyle(() => {
return {
transform: [{ translateX: x.value }, { translateY:y.value }],
};
});
const eventHandler = useAnimatedGestureHandler({
onStart: (event, ctx) => {
ctx.startX = x.value;
ctx.startY = y.value;
},
onActive: (event, ctx) => {
x.value = ctx.startX + event.translationX;
y.value = ctx.startY + event.translationY;
},
onEnd: (event, ctx) => {
x.value = withSpring(startingPosition);
y.value = withSpring(startingPosition);
},
});
return (
<PanGestureHandler onGestureEvent={eventHandler}>
<Animated.View style={animatedStyle}>{props.children}</
Animated.View>
</PanGestureHandler>
);
};
const Example = () => {
return (
<View style={styles.container}>
<Snappable>
<View style={styles.box} />
</Snappable>
</View>
);
};
export default Example;
const BOX_SIZE = 100;
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
box: {
width: BOX_SIZE,
height: BOX_SIZE,
borderColor: '#F5FCFF',
alignSelf: 'center',
backgroundColor: 'plum',
margin: BOX_SIZE / 2,
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment