Animated API: що це, можливості бібліотеки та принцип роботи

Автор: IT Sectr Опубліковано: 2026-07-06 Час читання: 8 хв

Animated API — це вбудована бібліотека декларативної анімації в React Native, яка забезпечує 60 FPS анімацію без навантаження на JavaScript-потік. За даними офіційної документації React Native 0.76 (2025), Animated API підтримує useNativeDriver для всіх типів анімацій, що переносить обчислення в нативний потік через UI Manager. Бібліотека дозволяє створювати складні ланцюжки анімацій, інтерактивні жести та інтерполяцію будь-яких стильових властивостей — від прозорості до трансформації.

Головне

  • Animated API — декларативна бібліотека анімації React Native з підтримкою нативного драйвера
  • Animated.Value — базовий елемент, що зберігає числове значення і підписує компоненти на зміни
  • useNativeDriver — опція, яка переносить анімацію в нативний потік для 60 FPS без джитеру
  • Інтерполяція — механізм перетворення числових діапазонів в кольори, кути, координати та масштаб
  • Композиція — послідовні, паралельні та ланцюжкові анімації через sequence, parallel та stagger

Що таке Animated API в React Native

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: Value, timing та spring

Основа 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: налаштування тривалості та easing

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: фізична анімація

Animated.spring реалізує пружинну модель анімації на основі закону Гука. Параметр friction (тертя) контролює кількість коливань: чим вище тертя, тим швидше зупинка. Параметр tension (натяження) визначає жорсткість пружини: високе натяження прискорює рух. Параметр velocity (швидкість) задає початкову швидкість для анімації з інерцією — критично важливо для анімацій, що йдуть за жестом користувача. Animated.spring не має фіксованої тривалості — анімація завершується, коли швидкість та амплітуда досягають порогових значень.

Animated.View, Animated.Text та інші компоненти

Animated API надає чотири вбудовані анімовані компоненти: Animated.View, Animated.Text, Animated.ScrollView та Animated.Image. Кожен з них — це оболонка над відповідним нативним компонентом, яка підтримує передачу Animated.Value у стильові властивості. Animated.View — найбільш використовуваний компонент, який приймає ті ж props, що й звичайний View, але з підтримкою анімованих значень у style. Animated.Text корисний для анімації кольору тексту або міжлітерного інтервалу. Animated.ScrollView дозволяє анімувати scrollTo та contentOffset. Animated.Image підтримує анімовану прозорість та масштаб під час завантаження зображень. Якщо потрібна анімація іншого компонента, використовуйте Animated.createAnimatedComponent(MyComponent).

js
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 може перетворюватися в жовтий-оранжевий-червоний.

js
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 запускає анімації з затримкою між стартом кожної — корисно для створення хвильових ефектів. Композиції можна вкладати одну в іншу: sequence з паралельних груп або parallel з sequence. Це дозволяє створювати складні ланцюжки: анімація появи елементів з затримкою, паралельний slide-in з fade-in, потім sequence з bounce та shake.

js
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 та продуктивність анімацій

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, всі анімовані властивості підтримуються через нативний драйвер, крім layout-базованих. Режим useNativeDriver рекомендується для всіх анімацій, де це можливо — це підвищує FPS з 30-40 до стабільних 60.

Анімація з жестами: PanResponder та Gesture Handler

PanResponder — вбудована система React Native для обробки жестів, яка відмінно інтегрується з Animated API. PanResponder надає колбеки onPanResponderMove та onPanResponderRelease, де можна оновлювати Animated.Value на основі позиції пальця. Для більш складних жестів — свайп, пінч, обертання — використовуйте бібліотеку react-native-gesture-handler, яка працює синхронно з анімаціями та забезпечує 60 FPS навіть при багатопальцевих жестах. Gesture Handler надає Animated.event — метод, який безпосередньо пов'язує жест з Animated.Value без ручної обробки колбеків. Комбінація Gesture Handler + Animated API — стандарт індустрії для інтерактивних анімацій в React Native додатках.

Animated.event: прив'язка жестів до значень

Animated.event — це метод, який пов'язує нативну подію (наприклад, gestureEvent) безпосередньо з Animated.Value. На відміну від ручної обробки в колбеку, Animated.event працює синхронно в нативному потоці та не потребує JavaScript-містка для кожного кадру. Це дає плавну анімацію навіть при швидких свайпах. Animated.event приймає масив мепінгів, де кожен елемент пов'язує поле події з Animated.Value. Підтримується вкладений доступ: Animated.event([{ nativeEvent: { translationX: xValue } }]).

Приклади коду з Animated API

Розглянемо три практичні приклади використання Animated API в React Native проектах. Перший приклад — анімація появи картки з послідовністю opacity + translateY. Другий приклад — анімація пульсації кнопки з використанням spring. Третій приклад — інтерактивний drag-елемент з PanResponder. Всі приклади використовують useNativeDriver = true та відповідають найкращим практикам React Native 0.76.

js
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

Spring-анімація створює природний ефект пульсації за рахунок фізичної моделі пружини. Налаштування низького тертя (2-4) та високого натяження (100-150) дає м'які коливання, які згасають природно. Використовуйте Animated.loop для нескінченної пульсації з циклом sequence: scale → 1.2, scale → 1.0. Пульсація застосовується для індикаторів завантаження, сповіщень та акцентних кнопок.

Часто задавані питання

Чим відрізняється Animated API від LayoutAnimation?

Animated API дає повний контроль над анімацією — тривалість, easing, інтерполяцію, композицію. LayoutAnimation — це вбудована система React Native для анімації змін layout з автоматичною інтерполяцією. Animated API вимагає явного оголошення Animated.Value та конфігурації, але дозволяє створювати складні ланцюжки. LayoutAnimation спрацьовує автоматично при зміні state і простіший у використанні, але обмежений у гнучкості.

Чи можна анімувати width та height через Animated API?

Так, width та height анімуються через Animated API, але не підтримують useNativeDriver. Для анімації layout-властивостей потрібен JavaScript-драйвер, оскільки нативний драйвер працює тільки з не-layout властивостями. Використовуйте Animated.Value з toValue для width/height та встановіть useNativeDriver в false. Для кращої продуктивності layout-анімацій розгляньте LayoutAnimation або react-native-reanimated.

Як зупинити поточну анімацію в Animated API?

Викличте метод stop() на об'єкті анімації, поверненому Animated.timing або Animated.spring. Приклад: animRef.stop(). Якщо анімація є частиною sequence або parallel, stop() зупиняє всю групу. Для перевірки статусу використовуйте колбек в start(callback) — він отримує об'єкт result з полем finished: false при примусовій зупинці.

Що таке Animated.ValueXY і коли його використовувати?

Animated.ValueXY — це контейнер для двомірних координат, який зберігає два Animated.Value: x та y. Використовуйте його для анімації позиції елемента на екрані — drag, pan, swipe. ValueXY надає готові методи getLayout() для стилів та getTranslateTransform() для трансформації. Це зручно при роботі з PanResponder, де потрібно анімувати обидві осі одночасно.

Як виміряти FPS анімації в React Native?

Використовуйте 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 або оптимізуйте кількість одночасних анімацій.

Підсумки

  • Animated API — декларативна бібліотека анімації React Native з підтримкою нативного драйвера для 60 FPS
  • Animated.Value — базовий контейнер числових значень, який підписує компоненти на зміни без перерендеру
  • Timing, Spring, Decay — три режими анімації: контрольована за часом, фізична пружинна та інерційна
  • Інтерполяція перетворює числові діапазони в кольори, кути, координати — основа складних візуальних ефектів
  • Композиція через sequence, parallel та stagger дозволяє створювати багатокрокові ланцюжки анімацій
  • useNativeDriver обов'язковий для продуктивності — переносить обчислення в нативний UI-потік
  • PanResponder та Gesture Handler інтегруються з Animated API для інтерактивних жестових анімацій
  • Використовуйте Animated.event для прямої прив'язки жестів до значень без JavaScript-містка

Ми розробимо мобільний застосунок під ключ

IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.

Обговорити проект

Читайте також