1import { View, Image } from 'react-native'; 2import { PanGestureHandler, TapGestureHandler } from 'react-native-gesture-handler'; 3import Animated, { 4 useAnimatedStyle, 5 useSharedValue, 6 useAnimatedGestureHandler, 7 withSpring, 8} from 'react-native-reanimated'; 9 10const AnimatedImage = Animated.createAnimatedComponent(Image); 11const AnimatedView = Animated.createAnimatedComponent(View); 12 13export default function EmojiSticker({ imageSize, stickerSource }) { 14 const translateX = useSharedValue(0); 15 const translateY = useSharedValue(0); 16 const scaleImage = useSharedValue(imageSize); 17 18 const imageStyle = useAnimatedStyle(() => { 19 return { 20 width: withSpring(scaleImage.value), 21 height: withSpring(scaleImage.value), 22 }; 23 }); 24 25 const onDoubleTap = useAnimatedGestureHandler({ 26 onActive: () => { 27 if (scaleImage.value !== imageSize * 2) { 28 scaleImage.value = scaleImage.value * 2; 29 } 30 }, 31 }); 32 33 const onDrag = useAnimatedGestureHandler({ 34 onStart: (event, context) => { 35 context.translateX = translateX.value; 36 context.translateY = translateY.value; 37 }, 38 onActive: (event, context) => { 39 translateX.value = event.translationX + context.translateX; 40 translateY.value = event.translationY + context.translateY; 41 }, 42 }); 43 44 const containerStyle = useAnimatedStyle(() => { 45 return { 46 transform: [ 47 { 48 translateX: translateX.value, 49 }, 50 { 51 translateY: translateY.value, 52 }, 53 ], 54 }; 55 }); 56 57 return ( 58 <PanGestureHandler onGestureEvent={onDrag}> 59 <AnimatedView style={[containerStyle, { top: -350 }]}> 60 <TapGestureHandler onGestureEvent={onDoubleTap} numberOfTaps={2}> 61 <AnimatedImage 62 source={stickerSource} 63 resizeMode="contain" 64 style={[imageStyle, { width: imageSize, height: imageSize }]} 65 /> 66 </TapGestureHandler> 67 </AnimatedView> 68 </PanGestureHandler> 69 ); 70} 71