๐ŸŽž๏ธ 51. React Native ์• ๋‹ˆ๋ฉ”์ด์…˜ ์™„์ „ ์ •๋ฆฌ โ€” Animated, Reanimated, Lottie ๋น„๊ต์™€ ์˜ˆ์‹œ

JM_Devยท2025๋…„ 6์›” 17์ผ
0
post-thumbnail

์•ฑ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ๊ฐ์„ฑ์ด๋‹ค.
๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ , ํ™”๋ฉด์ด ์ „ํ™˜๋˜๊ณ , ๋กœ๋”ฉ ์Šคํ”ผ๋„ˆ๊ฐ€ ๋Œ์•„๊ฐ€๋Š” ๋ชจ๋“  ์ˆœ๊ฐ„์ด
์œ ์ €์—๊ฒŒ โ€œ์ด ์•ฑ ๋ถ€๋“œ๋Ÿฝ๊ณ  ์ •๊ตํ•˜๋„ค?โ€๋ผ๋Š” ์ธ์ƒ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์€ React Native์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋„๊ตฌ๋“ค์„ ์ •๋ฆฌํ•˜๊ณ 
์–ด๋–ค ์ƒํ™ฉ์— ์–ด๋–ค ๋ฐฉ์‹์ด ์ ํ•ฉํ•œ์ง€ ์ •๋ฆฌํ•œ ๊ธ€์ด๋‹ค.


โœ… 1. Animated API (๊ธฐ๋ณธ ์ œ๊ณต)

React Native์—์„œ ๊ธฐ๋ณธ ์ œ๊ณตํ•˜๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์Šคํ…œ

๐Ÿ”ง ์˜ˆ์ œ: ํˆฌ๋ช…๋„ ์กฐ์ ˆ

const fadeAnim = useRef(new Animated.Value(0)).current;

useEffect(() => {
  Animated.timing(fadeAnim, {
    toValue: 1,
    duration: 500,
    useNativeDriver: true,
  }).start();
}, []);

return (
  <Animated.View style={{ opacity: fadeAnim }}>
    <Text>์• ๋‹ˆ๋ฉ”์ด์…˜ ์ปดํฌ๋„ŒํŠธ</Text>
  </Animated.View>
);

โœ… ๊ฐ„๋‹จํ•œ ์• ๋‹ˆ๋ฉ”์ด์…˜์— ์ ํ•ฉ
โœ… useNativeDriver: true๋กœ GPU ๊ธฐ๋ฐ˜ ์„ฑ๋Šฅ ํ™•๋ณด ๊ฐ€๋Šฅ
โŒ ๋ณต์žกํ•œ ์—ฐ์‚ฐ, ์ œ์Šค์ฒ˜์™€์˜ ์—ฐ๋™์—๋Š” ํ•œ๊ณ„


๐Ÿ” 2. Reanimated 2

์„ฑ๋Šฅ์ด ์ค‘์š”ํ•˜๊ฑฐ๋‚˜, ์ œ์Šค์ฒ˜/์Šคํฌ๋กค ์—ฐ๋™์ด ํ•„์š”ํ•  ๋•Œ ์„ ํƒ

npm install react-native-reanimated
  • ์™„์ „ํ•œ JS-to-Native bridge ์ตœ์ ํ™”
  • useSharedValue, withTiming, useAnimatedStyle ๋“ฑ์„ ์‚ฌ์šฉ

๐Ÿ”ง ์˜ˆ์ œ: ์œ„์น˜ ์ด๋™

const offset = useSharedValue(0);

const animatedStyles = useAnimatedStyle(() => ({
  transform: [{ translateY: offset.value }],
}));

return (
  <Animated.View style={animatedStyles} />
);

โœ… ์„ฑ๋Šฅ ์ตœ๊ณ 
โœ… ์ œ์Šค์ฒ˜ ํ•ธ๋“ค๋ง, ์Šคํฌ๋กค ์—ฐ๋™์— ๊ฐ•ํ•จ
โŒ ๋Ÿฌ๋‹ ์ปค๋ธŒ ์žˆ์Œ, ์„ค์น˜ ๋ณต์žก


๐ŸŽจ 3. Lottie

๋””์ž์ด๋„ˆ๊ฐ€ ๋งŒ๋“  JSON ์• ๋‹ˆ๋ฉ”์ด์…˜ ํŒŒ์ผ์„ ๊ทธ๋Œ€๋กœ ์•ฑ์—์„œ ์žฌ์ƒ

npm install lottie-react-native
import LottieView from 'lottie-react-native';

<LottieView
  source={require('./animation.json')}
  autoPlay
  loop
/>

โœ… ๊ณ ํ€„๋ฆฌํ‹ฐ ์ผ๋Ÿฌ์ŠคํŠธ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ตฌํ˜„
โœ… ๋กœ๋”ฉ ์ธ๋””์ผ€์ดํ„ฐ, ์„ฑ๊ณต ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋“ฑ์— ์œ ๋ฆฌ
โŒ ์‚ฌ์šฉ์ž ์ธํ„ฐ๋ž™์…˜๊ณผ๋Š” ๋‹ค์†Œ ๋ถ„๋ฆฌ๋จ (๋™๊ธฐํ™” ์–ด๋ ต)


๐Ÿ“Š ์ƒํ™ฉ๋ณ„ ์„ ํƒ ๊ธฐ์ค€

๋ชฉ์ ์ถ”์ฒœ ๋„๊ตฌ
๋ฒ„ํŠผ ๋ˆ„๋ฅผ ๋•Œ ํšจ๊ณผAnimated
์ œ์Šค์ฒ˜ ๊ธฐ๋ฐ˜ ์Šฌ๋ผ์ด๋“œReanimated
์Šคํฌ๋กค ๋”ฐ๋ผ ์›€์ง์ด๋Š” ์ปดํฌ๋„ŒํŠธReanimated
๋กœ๋”ฉ/์„ฑ๊ณต ์• ๋‹ˆ๋ฉ”์ด์…˜Lottie
๋ณต์žกํ•œ ์ „ํ™˜ ์• ๋‹ˆ๋ฉ”์ด์…˜Reanimated + react-native-gesture-handler

๐Ÿง  ์‹ค์ „ ํŒ

ํ•ญ๋ชฉ์ „๋žต
๋ฆฌ๋ Œ๋” ๋ฐฉ์ง€useRef ๋˜๋Š” useSharedValue ์‚ฌ์šฉ
์„ฑ๋Šฅ ์ตœ์ ํ™”useNativeDriver: true๋Š” ํ•ญ์ƒ ๊ณ ๋ ค
๋น„๋™๊ธฐ ์‹œ์ž‘ ์‹œ์ Animated.sequence, delay() ๋“ฑ ์กฐํ•ฉ
๋ชจ๋‹ฌ ์• ๋‹ˆ๋ฉ”์ด์…˜์—ด๊ธฐ/๋‹ซ๊ธฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ถ„๋ฆฌ ๊ตฌํ˜„ ์ถ”์ฒœ

๐Ÿ“ ๋‚ด๊ฐ€ ๋А๋‚€ ์ 

์ฒ˜์Œ์—” ๊ทธ๋ƒฅ opacity ์ •๋„๋งŒ ์ค˜๋„ ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ
ํ™”๋ฉด ์ „ํ™˜, ์Šค์™€์ดํ”„, ๋“œ๋ž˜๊ทธ, ํƒญ ๋ฐ˜์‘์„ฑ ๋“ฑ
์•ฑ์˜ ๊ณ ๊ธ‰์Šค๋Ÿฌ์šด ๋А๋‚Œ์€ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์ฑ…์ž„์ง€๊ณ  ์žˆ๋‹ค๋Š” ๊ฑธ ์•Œ๊ฒŒ ๋๋‹ค.

์ง€๊ธˆ์€ ๋ฒ„ํŠผ ํšจ๊ณผ โ†’ Animated,
์ œ์Šค์ฒ˜ โ†’ Reanimated,
๋กœ๋”ฉ/์„ฑ๊ณต โ†’ Lottie
์ด๋Ÿฐ ๊ตฌ์กฐ๋กœ ์“ฐ๊ณ  ์žˆ๊ณ ,
UI ํ€„๋ฆฌํ‹ฐ๊ฐ€ ๋ˆˆ์— ๋„๊ฒŒ ์ข‹์•„์กŒ๋‹ค๋Š” ํ”ผ๋“œ๋ฐฑ๋„ ์ข…์ข… ๋ฐ›๋Š”๋‹ค.


๐ŸŽฌ โ€œ์• ๋‹ˆ๋ฉ”์ด์…˜์€ ๊ธฐ๋Šฅ์ด ์•„๋‹ˆ๋ผ, ๊ฐ๋™์ด๋‹ค.โ€


profile
๊ฐœ๋ฐœ์ž๋กœ ์ทจ์—…์„ ์ค€๋น„ ์ค‘ ์ด๋ฉฐ, ์—ด์‹ฌํžˆ ๊ณต๋ถ€ ์ค‘ ์ž…๋‹ˆ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€