Animated API는 JavaScript 스레드에 부하를 주지 않고 60 FPS 애니메이션을 제공하는 React Native 내장 선언적 애니메이션 라이브러리입니다. React Native 0.76 (2025) 공식 문서에 따르면 Animated API는 모든 유형의 애니메이션에서 useNativeDriver를 지원하며, UI Manager를 통해 계산을 네이티브 스레드로 옮깁니다. 이 라이브러리는 복잡한 애니메이션 체인, 대화형 제스처, 그리고 투명도부터 변환까지의 모든 스타일 포크스의 보간을 생성할 수 있습니다.
주요 포인트
Animated API는 모바일 애플리케이션에서 부드러우고 고성능인 애니메이션을 생성하도록 설계된, React Native 코에 통합된 선언적 애니메이션 라이브러리입니다. 웹 개발의 CSS 애니메이션과 달리, Animated API는 JavaScript 브리지 또는 네이티브 드라이버를 통해 네이티브 UI 스레드와 직접 작동합니다. 이 라이브러리는 숫자형 값을 저장하고 자동으로 모든 의존 컴포넌트를 변경에 구독하는 컨테너인 Animated.Value의 개념을 중심으로 구축되었습니다. Animated.timing 또는 Animated.spring으로 값이 변경되면, 라이브러리는 React 컴포넌트를 다시 렌더링하지 않고 중간 상태를 계산하여 60 FPS를 유지합니다. Animated API는 transform, opacity, width, height, top, left 그리고 backgroundColor를 포함한 모든 스타일 포크스를 지원합니다. React Native 문서는 높은 성능과 두 플랫폼에서 예측 가능한 동작이 필요한 모든 애니메이션 시나리오에서 Animated API를 권장합니다.
Animated API의 기반은 Animated.Value입니다. 생성자 new Animated.Value(0)를 통해 초기화되는 숫자형 값 컨테너입니다. 각 Animated.Value는 초기 숫자를 저장하고 애니메이션 메서드를 제공합니다: timing, spring, decay. timing 메서드는 지속 시간, 지연 및 easing 매개변수를 사용하여 선형 또는 easing 애니메이션을 생성합니다. spring 메서드는 마찰, 장력 및 속도 매개변수를 사용하여 물리적 스프링 애니메이션을 구현합니다. decay 메서드는 관성과 감쇠를 가진 애니메이션을 생성합니다 — 스와이프와 스크롤에 유용합니다. 모든 메서드는 Animated.Composite 객체를 반환하며, start()로 시작하고 stop()으로 멈추일 수 있습니다. 애니메이션은 별도의 스레드에서 실행됩니다: useNativeDriver = true일 때 계산은 네이티브 UI 스레드에서 일어나고 JavaScript 스레드는 이벤트 처리와 로직을 위해 자유로운 상태로 남습니다.
Animated.timing은 제어된 지속 시간을 가진 기본 애니메이션 메서드입니다. 구성을 수령합니다: toValue, duration (기본 500ms), easing (기본 Easing.linear), delay. Easing 모듈의 Easing 함수는 비선형 가속을 가능하게 합니다: Easing.bezier, Easing.elastic, Easing.bounce. 균일 속도 애니메이션에는 Easing.linear를, 자연스러운 가속에는 Easing.inOut을 사용하세요. 중요: Animated.timing은 장치 부하와 관계없이 지정된 시간 내에 toValue에서 정확하게 애니메이션이 끝나도록 보장합니다.
Animated.spring은 훁의 법칙에 기반한 스프링 애니메이션 모델을 구현합니다. friction (마찰) 매개변수는 진동 회수를 제어합니다: 마찰이 높을수록 멈추는 속도가 빠릅니다. tension (장력) 매개변수는 스프링의 강성을 결정합니다: 높은 장력은 운동을 가속합니다. velocity (속도) 매개변수는 관성이 있는 애니메이션의 초기 속도를 설정합니다 — 사용자 제스처를 따르는 애니메이션에 그렇게 중요합니다. Animated.spring에는 고정 지속 시간이 없습니다 — 속도와 진폭이 문터값에 도달하면 애니메이션이 완료됩니다.
Animated API는 네 가지 내장 애니메이트 컴포넌트를 제공합니다: Animated.View, Animated.Text, Animated.ScrollView, Animated.Image. 각각은 해당 네이티브 컴포넌트의 래퍼로 스타일 포크스에 Animated.Value를 전달하는 것을 지원합니다. Animated.View는 가장 많이 사용되는 컴포넌트로, 일반 View와 동일한 props를 수렵하지만 style에 애니메이트 값을 지원합니다. Animated.Text는 텍스트 색상 또는 글자 간격을 애니메이트하는 데 유용합니다. Animated.ScrollView는 scrollTo와 contentOffset을 애니메이트할 수 있습니다. Animated.Image는 이미지 로딩 중에 애니메이트된 투명도와 스케일을 지원합니다. 다른 컴포넌트를 애니메이트해야 한다면 Animated.createAnimatedComponent(MyComponent)를 사용하세요.
import React from 'react';
import { Animated, View, Button } from 'react-native';
const FadeInView = () => {
const opacity = useRef(new Animated.Value(0)).current;
const fadeIn = () => {
Animated.timing(opacity, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start();
};
return (
View
Animated.View { style: [{ opacity }] }
Button title="Fade In" onPress={fadeIn}
);
};
보간법은 Animated.Value의 입력 숫자 범위를 다른 유형의 출력 값으로 변환하는 메커니즘입니다. interpolate 메서드는 inputRange (입력 값 배열) 및 outputRange (출력 값 배열)이 있는 구성을 수렵합니다. outputRange 유형: 숫자 (좌표, 투명도), 문자열 ('deg'를 통한 회전 각), 16진수 색 ('#ff0000'), 변환 객체. 보간법은 easing과 extrapolate (지정 범위 밖의 동작: clamp, extend, identity)을 지원합니다. 예를 들어, 드래그 제스처에서 손가락 위치 0부터 200을 투명도 1에서 0으로 변환하여 스와이프 시 페이드 효과를 만들 수 있습니다. 보간법 시스템은 복잡한 다단계 애니메이션을 생성할 수 있습니다: 값 0-0.5-1.0을 노란-주황-빨간으로 변환할 수 있습니다.
const spinValue = new Animated.Value(0);
Animated.timing(spinValue, {
toValue: 1,
duration: 3000,
easing: Easing.linear,
useNativeDriver: true,
}).start();
const spin = spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
});
Animated API는 세 가지 애니메이션 작곡 모드를 지원합니다: Animated.sequence, Animated.parallel, Animated.stagger. Animated.sequence는 애니메이션을 차례로 실행합니다: 이전 애니메이션이 끝나면 다음이 시작됩니다. Animated.parallel은 모든 애니메이션을 한 개의 공유 완료 콜백으로 동시에 실행합니다. Animated.stagger는 각 시작 사이에 지연을 두고 애니메이션을 실행합니다 — 파도 효과를 만드는 데 유용합니다. 작곡은 중첩이 가능합니다: 병렬 그룹의 순차 또는 순차의 병렬. 이를 통해 복잡한 체인을 만들 수 있습니다: 지연이 있는 요소 나타남 애니메이션, fade-in이 있는 병렬 slide-in, 그리고 bounce와 shake의 순차.
Animated.sequence([
Animated.timing(fadeAnim, {
toValue: 1,
duration: 500,
useNativeDriver: true,
}),
Animated.parallel([
Animated.timing(scaleAnim, {
toValue: 1.1,
duration: 200,
useNativeDriver: true,
}),
Animated.spring(colorAnim, {
toValue: 1,
friction: 4,
useNativeDriver: true,
}),
]),
]).start();
useNativeDriver는 모든 애니메이션 로직을 JavaScript 스레드에서 네이티브 UI 스레드로 옮기는 애니메이션 구성 옵션입니다. useNativeDriver가 없으면 애니메이션은 JavaScript 브리지를 통해 실행됩니다: 값이 변경될 때마다 네이티브 스레드로 전송되며, JS 스레드가 비동기 작업으로 바쁘 때 지연이 발생합니다. useNativeDriver = true일 때 Animated.Value는 네이티브 측에서 직접 업데이트되어 JavaScript 스레드를 이벤트 처리, API 요청 및 React 재조화를 위해 자유로가 유지됩니다. 제한: useNativeDriver는 비-레이아웃 포크스만 지원합니다 — opacity, transform, backgroundColor (PlatformColor 통해). 레이아웃 포크스 (width, height, top, left)에는 NativeAnimatedModule 또는 LayoutAnimation이 필요합니다. React Native 0.76에 따르면 레이아웃 기반을 제외한 모든 애니메이트 포크스가 네이티브 드라이버를 통해 지원됩니다. useNativeDriver 모드는 가능한 경우 모든 애니메이션에 권장됩니다 — FPS를 30-40에서 안정적인 60으로 농임니다.
PanResponder는 Animated API와 잘 융합되는 내장 React Native 제스처 처리 시스템입니다. PanResponder는 손가락 위치에 기반하여 Animated.Value를 업데이트할 수 있는 onPanResponderMove 및 onPanResponderRelease 콜백을 제공합니다. 더 복잡한 제스처 (스와이프, 한짐, 회전)에는 react-native-gesture-handler 라이브러리를 사용하세요. 이 라이브러리는 애니메이션과 동기로 작동하며 다중 손가락 제스처에서도 60 FPS를 제공합니다. Gesture Handler는 수동 콜백 처리 없이 제스처를 Animated.Value에 직접 바인드하는 메서드인 Animated.event를 제공합니다. Gesture Handler + Animated API의 조합은 React Native 애플리케이션에서 대화형 애니메이션의 업계 표준입니다.
Animated.event는 네이티브 이벤트 (예: gestureEvent)를 Animated.Value에 직접 바인드하는 메서드입니다. 콜백의 수동 처리와 달리 Animated.event는 네이티브 스레드에서 동기적으로 작동하며 모든 프레임에 JavaScript 브리지가 필요하지 않습니다. 이를 통해 빠른 스와이프에서도 부드러운 애니메이션이 가능합니다. Animated.event는 매핑의 배열을 수렵하며, 각 요소가 이벤트 필드를 Animated.Value에 바인드합니다. 중첩 액세스가 지원됩니다: Animated.event([{ nativeEvent: { translationX: xValue } }]).
React Native 프로젝트에서 Animated API를 사용하는 세 가지 실용 예를 살펴봅시다. 첫 번째 예는 opacity + translateY 순차를 사용한 카드 나타남 애니메이션입니다. 둘째 예는 spring을 사용한 버튼 펄스 애니메이션입니다. 셨째 예는 PanResponder를 사용한 대화형 드래그 요소입니다. 모든 예는 useNativeDriver = true를 사용하고 React Native 0.76의 최고 실천을 따릅니다.
const CardWithAnimation = () => {
const anim = useRef(new Animated.Value(0)).current;
React.useEffect(() => {
Animated.spring(anim, {
toValue: 1,
friction: 6,
tension: 40,
useNativeDriver: true,
}).start();
}, []);
const translateY = anim.interpolate({
inputRange: [0, 1],
outputRange: [50, 0],
});
return (
Animated.View {
style: [{ opacity: anim, transform: [{ translateY }] }]
}
);
};
Spring 애니메이션은 물리적 스프링 모델을 통해 자연스러운 펄스 효과를 만듭니다. 낮은 마찰 (2-4)과 높은 장력 (100-150) 설정으로 자연스럽게 감쇠되는 부드러운 진동이 만들어집니다. 무한 펄스를 위해 순차 사이퀔 (scale → 1.2, scale → 1.0)으로 Animated.loop를 사용하세요. 펄스는 로딩 지표, 알림 및 강조 버튼에 사용됩니다.
자주 묻는 질문
Animated API는 애니메이션을 완전히 제어합니다 — 지속 시간, easing, 보간법, 작곡. LayoutAnimation은 자동 보간으로 레이아웃 변경을 애니메이트하는 내장 React Native 시스템입니다. Animated API는 Animated.Value와 구성의 명시적 선언이 필요하지만 복잡한 체인을 만들 수 있습니다. LayoutAnimation은 상태 변경에 자동으로 작동하고 사용하기 쉽지만 유연성이 제한됩니다.
네, width와 height는 Animated API를 통해 애니메이트할 수 있지만 useNativeDriver를 지원하지 않습니다. 레이아웃 포크스 애니메이션은 JavaScript 드라이버가 필요합니다. width/height에는 toValue와 함께 Animated.Value를 사용하고 useNativeDriver를 false로 설정하세요. 더 나은 레이아웃 애니메이션 성능을 위해 LayoutAnimation 또는 react-native-reanimated을 고려하세요.
Animated.timing 또는 Animated.spring이 반환한 애니메이션 객체의 stop() 메서드를 호출하세요. 예: animRef.stop(). 애니메이션이 sequence 또는 parallel의 일부인 경우 stop()은 그룹 전체를 멈춅니다. 상태를 확인하려면 start(callback)의 콜백을 사용하세요. 강제 멈추기의 경우 result 객체에 finished: false가 포함됩니다.
Animated.ValueXY는 2차원 좌표를 위한 컨테너로 x와 y의 두 Animated.Value를 저장합니다. 화면에서 요소 위치를 애니메이트하는 데 사용합니다 (drag, pan, swipe). ValueXY는 스타일을 위한 편리한 getLayout() 그리고 변환을 위한 getTranslateTransform() 메서드를 제공합니다. 두 축을 동시에 애니메이트해야 하는 PanResponder에서 편리합니다.
개발자 메뉴 (Cmd+D / Cmd+M)에 포함된 React Native 성능 모니터를 사용하세요. FPS 모니터를 켜면 실시간으로 UI FPS와 JS FPS가 표시됩니다. 프로그래밍 측정을 위해 import { InteractionManager }를 사용하여 애니메이션 완료를 추적합니다. 안정적인 60 UI FPS와 50+ JS FPS는 잘 최적화된 애니메이션의 증거입니다. UI FPS가 30 미만으로 떨어지면 useNativeDriver를 비활성화하거나 동시 실행 애니메이션 수를 최적화하세요.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.