Animated API — это встроенная библиотека декларативной анимации в React Native, которая обеспечивает 60 FPS анимацию без нагрузки на JavaScript-тред. По данным официальной документации React Native 0.76 (2025), Animated API поддерживает useNativeDriver для всех типов анимаций, что переносит вычисления в нативный поток через UI Manager. Библиотека позволяет создавать сложные цепочки анимаций, интерактивные жесты и интерполяцию любых стилевых свойств — от прозрачности до трансформации.
Главное
Animated API — это декларативная библиотека анимации, встроенная в ядро React Native и предназначенная для создания плавных, производительных анимаций в мобильных приложениях. В отличие от CSS-анимаций в веб-разработке, Animated API работает непосредственно с нативным потоком UI через JavaScript-мост или нативный драйвер. Библиотека построена вокруг концепции 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 хранит начальное число и предоставляет методы animate: timing, spring и decay. Метод timing создаёт линейную или easing-анимацию с параметрами duration, delay и easing. Метод spring реализует физическую пружинную анимацию с параметрами friction, tension и velocity. Метод 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 (трение) контролирует количество колебаний: чем выше friction, тем быстрее остановка. Параметр tension (натяжение) определяет жёсткость пружины: высокий tension ускоряет движение. Параметр velocity задаёт начальную скорость для анимации с инерцией — критически важно для анимаций, следующих за жестом пользователя. Animated.spring не имеет фиксированной длительности — анимация завершается, когда скорость и амплитуда достигают пороговых значений.
Animated API предоставляет четыре встроенных анимированных компонента: Animated.View, Animated.Text, Animated.ScrollView и Animated.Image. Каждый из них — это обёртка над соответствующим нативным компонентом, которая поддерживает передачу Animated.Value в стилевые свойства. Animated.View — самый используемый компонент, принимающий те же props, что и обычный View, но с поддержкой анимированных значений в style. Animated.Text полезен для анимации цвета текста или inter-letter spacing. 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'), hex-цвета ('#ff0000'), объекты трансформации. Интерполяция поддерживает easing и extrapolate — поведение за пределами заданного диапазона (clamp, extend, identity). Например, при drag-жесте можно преобразовать позицию пальца от 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 запускает анимации с задержкой между стартом каждой — delayed start, полезно для создания волновых эффектов. Композиции можно вкладывать друг в друга: sequence из parallel групп или parallel из sequence. Это позволяет создавать сложные цепочки: анимация появления элементов с задержкой, параллельный slide-in с fade-in, затем sequence из 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 поддерживает только не-layout свойства — opacity, transform, backgroundColor (через PlatformColor). Для свойств layout (width, height, top, left) требуется NativeAnimatedModule или LayoutAnimation. По данным React Native 0.76, all animated properties поддерживаются через native driver, кроме layout-based. Режим useNativeDriver рекомендуется для всех анимаций, где это возможно — это повышает FPS с 30-40 до стабильных 60.
PanResponder — встроенная система React Native для обработки жестов, которая отлично интегрируется с Animated API. PanResponder предоставляет колбэки onPanResponderMove и onPanResponderRelease, где можно обновлять Animated.Value на основе позиции пальца. Для более сложных жестов — swipe, pinch, rotation — используйте библиотеку react-native-gesture-handler, которая работает синхронно с анимациями и обеспечивает 60 FPS даже при многопальцевых жестах. Gesture Handler предоставляет Animated.event — метод, который напрямую связывает жест с Animated.Value без ручной обработки колбэков. Комбинация Gesture Handler + Animated API — стандарт индустрии для интерактивных анимаций в React Native приложениях.
Animated.event — это метод, который связывает нативное событие (например, gestureEvent) напрямую с Animated.Value. В отличие от ручной обработки в колбэке, Animated.event работает синхронно в нативном потоке и не требует JavaScript-моста для каждого кадра. Это даёт плавную анимацию даже при быстрых свайпах. Animated.event принимает массив маппингов, где каждый элемент связывает поле события с Animated.Value. Поддерживается вложенный доступ: Animated.event([{ nativeEvent: { translationX: xValue } }]).
Рассмотрим три практических примера использования Animated API в React Native проектах. Первый пример — анимация появления карточки с последовательностью opacity + translateY. Второй пример — анимация пульсации кнопки с использованием spring. Третий пример — интерактивный drag-элемент с 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-анимация создаёт естественный эффект пульсации за счёт физической модели пружины. Настройка low friction (2-4) и high tension (100-150) даёт мягкие колебания, которые затухают естественно. Используйте Animated.loop для бесконечной пульсации с циклом sequence: scale → 1.2, scale → 1.0. Пульсация применяется для индикаторов загрузки, уведомлений и акцентных кнопок.
Часто задаваемые вопросы
Animated API даёт полный контроль над анимацией — длительность, easing, интерполяцию, композицию. LayoutAnimation — это встроенная система React Native для анимации изменений layout с автоматической интерполяцией. Animated API требует явного объявления Animated.Value и конфигурации, но позволяет создавать сложные цепочки. LayoutAnimation срабатывает автоматически при изменении state и проще в использовании, но ограничен в гибкости.
Да, width и height анимируются через Animated API, но не поддерживают useNativeDriver. Для анимации layout-свойств требуется JavaScript-драйвер, так как нативный драйвер работает только с не-layout свойствами. Используйте Animated.Value с toValue для width/height и установите useNativeDriver в false. Для лучшей производительности layout-анимаций рассмотрите LayoutAnimation или react-native-reanimated.
Вызовите метод stop() на объекте анимации, возвращённом Animated.timing или Animated.spring. Пример: animRef.stop(). Если анимация является частью sequence или parallel, stop() останавливает всю группу. Для проверки статуса используйте колбэк в start(callback) — он получает объект result с полем finished: false при принудительной остановке.
Animated.ValueXY — это контейнер для двухмерных координат, хранящий два Animated.Value: x и y. Используйте его для анимации позиции элемента на экране — drag, pan, swipe. ValueXY предоставляет готовые методы getLayout() для стилей и getTranslateTransform() для трансформации. Это удобно при работе с PanResponder, где нужно анимировать обе оси одновременно.
Используйте React Native Performance Monitor, встроенный в dev-меню (Cmd+D / Cmd+M). Включите FPS Monitor — он покажет UI FPS и JS FPS в реальном времени. Для программного измерения используйте import { InteractionManager } для отслеживания завершения анимаций. Стабильные 60 UI FPS и 50+ JS FPS — показатель хорошо оптимизированной анимации. Если UI FPS падает ниже 30, отключите useNativeDriver или оптимизируйте количество одновременно работающих анимаций.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также