Перейти к содержанию

Animated

Библиотека Animated разработана для того, чтобы сделать анимацию плавной, мощной и простой в создании и поддержке. Animated фокусируется на декларативных отношениях между входами и выходами, настраиваемых преобразованиях между ними и методах start/stop для управления выполнением анимации по времени.

Основной рабочий процесс создания анимации заключается в создании Animated.Value, подключении его к одному или нескольким атрибутам стиля анимированного компонента, а затем в обновлении анимации с помощью Animated.timing().

Внимание

Не изменяйте анимированное значение напрямую. Вы можете использовать хук useRef для возврата изменяемого объекта ref. Свойство current этого ref-объекта инициализируется как заданный аргумент и сохраняется в течение всего жизненного цикла компонента.

Пример

Следующий пример содержит View, который будет затухать и исчезать на основе анимированного значения fadeAnim.

Обратитесь к руководству "Анимации", чтобы увидеть дополнительные примеры Animated в действии.

Обзор

Существует два типа значений, которые можно использовать с Animated:

Animated.Value может связываться со свойствами стиля или другими пропсами, а также может быть интерполирован. Одно Animated.Value может управлять любым количеством свойств.

Настройка анимации

Animated предоставляет три типа анимации. Каждый тип анимации предоставляет определенную кривую анимации, которая управляет тем, как ваши значения изменяются от начального значения до конечного:

  • Animated.decay() начинается с начальной скорости и постепенно замедляется до остановки.
  • Animated.spring() предоставляет базовую физическую модель пружины.
  • Animated.timing() анимирует значение с течением времени, используя easing functions.

В большинстве случаев вы будете использовать timing(). По умолчанию она использует симметричную кривую easeInOut, которая передает постепенное ускорение объекта до полной скорости и завершается постепенным замедлением до остановки.

Работа с анимацией

Анимация запускается вызовом start() для вашей анимации. start() принимает обратный вызов завершения, который будет вызван, когда анимация завершится. Если анимация завершилась нормально, то обратный вызов завершения будет вызван с {finished: true}. Если анимация завершена, потому что stop() был вызван до того, как она успела закончиться (например, потому что она была прервана жестом или другой анимацией), то она получит {finished: false}.

1
2
3
Animated.timing({}).start(({ finished }) => {
    /* completion callback */
});

Использование родного драйвера

Используя нативный драйвер, мы отправляем все данные об анимации в нативный поток до начала анимации, что позволяет нативному коду выполнять анимацию в потоке UI без необходимости проходить через мост на каждом кадре. После запуска анимации поток JS может быть заблокирован без ущерба для анимации.

Вы можете использовать родной драйвер, указав useNativeDriver: true в конфигурации анимации. Подробнее см. в руководстве Animations.

Анимируемые компоненты

Анимированными могут быть только анимируемые компоненты. Эти уникальные компоненты выполняют магию привязки анимированных значений к свойствам и выполняют целенаправленные нативные обновления, чтобы избежать затрат на процесс рендеринга и согласования React на каждом кадре. Они также обрабатывают очистку при размонтировании, поэтому по умолчанию они безопасны.

  • createAnimatedComponent() можно использовать для создания анимируемого компонента.

Animated экспортирует следующие анимируемые компоненты, используя вышеуказанную обертку:

  • Animated.Image
  • Animated.ScrollView
  • Animated.Text
  • Animated.View
  • Animated.FlatList
  • Animated.SectionList

Составление анимации

Анимации также можно комбинировать сложным образом с помощью функций композиции:

  • Animated.delay() запускает анимацию после заданной задержки.
  • Animated.parallel() запускает несколько анимаций одновременно.
  • Animated.sequence() запускает анимации по порядку, ожидая завершения каждой перед запуском следующей.
  • Animated.stagger() запускает анимации по порядку и параллельно, но с последовательными задержками.

Анимации также можно объединять в цепочки, задавая toValue одной анимации как Animated.Value другой. См. раздел Отслеживание динамических значений в руководстве по анимации.

По умолчанию, если одна анимация остановлена или прервана, то все остальные анимации в группе также останавливаются.

Объединение анимированных значений

Вы можете объединить два анимированных значения путем сложения, вычитания, умножения, деления или по модулю, чтобы получить новое анимированное значение:

Интерполяция

Функция interpolate() позволяет сопоставить входные диапазоны с различными выходными диапазонами. По умолчанию она экстраполирует кривую за пределы заданных диапазонов, но вы также можете зажать выходное значение. По умолчанию она использует линейную интерполяцию, но также поддерживает функции смягчения.

Подробнее об интерполяции читайте в руководстве Анимация.

Обработка жестов и других событий

Жесты, такие как панорамирование или прокрутка, и другие события могут отображаться непосредственно на анимированные значения с помощью Animated.event(). Для этого используется структурированный синтаксис карты, чтобы можно было извлекать значения из сложных объектов событий. Первый уровень — это массив, позволяющий отображать несколько аргументов, и этот массив содержит вложенные объекты.

Например, при работе с жестами горизонтальной прокрутки вы должны сделать следующее, чтобы сопоставить event.nativeEvent.contentOffset.x с scrollX (Animated.Value):

1
2
3
4
5
6
7
8
9
onScroll={Animated.event(
   // scrollX = e.nativeEvent.contentOffset.x
   [{nativeEvent: {
        contentOffset: {
          x: scrollX
        }
      }
    }]
)}

Методы

Когда заданное значение является ValueXY, а не Value, каждый параметр конфигурации может быть вектором вида {x: ..., y: ...} вместо скаляра.

decay()

1
static decay(value, config): CompositeAnimation;

Анимирует значение от начальной скорости до нуля на основе коэффициента затухания.

Config — это объект, который может иметь следующие параметры:

  • velocity: Начальная скорость. Требуется.
  • deceleration: Скорость замедления. По умолчанию 0.997.
  • isInteraction: Создает ли эта анимация "ручку взаимодействия" на InteractionManager. По умолчанию true.
  • useNativeDriver: Использует родной драйвер, если true. Требуется.

timing()

1
static timing(value, config): CompositeAnimation;

Анимирует значение вдоль кривой смягчения с определенным временем. Модуль Easing имеет множество предопределенных кривых, или вы можете использовать свою собственную функцию.

Config — это объект, который может иметь следующие параметры:

  • duration: Продолжительность анимации (миллисекунды). По умолчанию 500.
  • easing: Функция облегчения для определения кривой. По умолчанию Easing.inOut(Easing.ease).
  • delay: Запуск анимации после задержки (миллисекунд). По умолчанию 0.
  • isInteraction: Создает ли эта анимация "ручку взаимодействия" на InteractionManager. По умолчанию true.
  • useNativeDriver: Использует родной драйвер, если true. Требуется.

spring()

1
static spring(value, config): CompositeAnimation;

Анимирует значение в соответствии с аналитической пружинной моделью, основанной на затухающем гармоническом колебании. Отслеживает состояние скорости для создания плавных движений по мере обновления toValue, и может быть соединен в цепочку.

Config — это объект, который может иметь следующие параметры.

Обратите внимание, что вы можете определить только один из параметров: отскок/скорость, натяжение/фрикцион или жесткость/демпфирование/масса, но не более одного:

Параметры трения/натяжения или отскока/скорости соответствуют модели пружины в Facebook Pop, Rebound и Origami.

  • friction: Управляет "прыгучестью"/перебором. По умолчанию 7.
  • tension: Управляет скоростью. По умолчанию 40.
  • speed: Управляет скоростью анимации. По умолчанию 12.
  • bounciness: Управляет прыгучестью. По умолчанию 8.

Указание жесткости/демпфирования/массы в качестве параметров заставляет Animated.spring использовать аналитическую модель пружины, основанную на уравнениях движения затухающего гармонического осциллятора. Такое поведение немного точнее и точнее соответствует физике, лежащей в основе динамики пружины, и близко имитирует реализацию в CASpringAnimation в iOS.

  • stiffness: Коэффициент жесткости пружины. По умолчанию 100.
  • damping: Определяет, насколько движение пружины должно быть затухающим из-за сил трения. По умолчанию 10.
  • mass: Масса объекта, прикрепленного к концу пружины. По умолчанию 1.

Другие варианты конфигурации следующие:

  • velocity: Начальная скорость объекта, прикрепленного к пружине. По умолчанию 0 (объект находится в состоянии покоя).
  • overhootClamping: Булево значение, указывающее, должна ли пружина быть зажата и не отскакивать. По умолчанию false.
  • restDisplacementThreshold: Порог смещения из состояния покоя, ниже которого пружина должна считаться находящейся в состоянии покоя. По умолчанию 0.001.
  • restSpeedThreshold: Скорость, при которой пружина должна считаться находящейся в состоянии покоя, в пикселях в секунду. По умолчанию 0.001.
  • delay: Запускать анимацию с задержкой (миллисекунды). По умолчанию 0.
  • isInteraction: Создает ли эта анимация "хэндл взаимодействия" на InteractionManager. По умолчанию true.
  • useNativeDriver: Использует родной драйвер, если true. Требуется.

add()

1
static add(a: Animated, b: Animated): AnimatedAddition;

Создает новое Анимированное значение, составленное из двух Анимированных значений, сложенных вместе.

subtract()

1
static subtract(a: Animated, b: Animated): AnimatedSubtraction;

Создает новое Анимированное значение путем вычитания второго Анимированного значения из первого Анимированного значения.

divide()

1
static divide(a: Animated, b: Animated): AnimatedDivision;

Создает новое Анимированное значение, состоящее из деления первого Анимированного значения на второе Анимированное значение.

multiply()

1
static multiply(a: Animated, b: Animated): AnimatedMultiplication;

Создает новое Анимированное значение, составленное из двух Анимированных значений, умноженных вместе.

modulo()

1
static modulo(a: Animated, modulus: number): AnimatedModulo;

Создает новое Анимированное значение, которое является (неотрицательным) модулем предоставленного Анимированного значения

diffClamp()

1
static diffClamp(a: Animated, min: number, max: number): AnimatedDiffClamp;

Создайте новое анимированное значение, которое ограничено между двумя значениями. Оно использует разницу между последними значениями, поэтому даже если значение находится далеко от границ, оно начнет меняться, когда значение снова начнет приближаться. (value = clamp(value + diff, min, max)).

Это полезно при использовании событий прокрутки, например, чтобы показать навигационную панель при прокрутке вверх и скрыть ее при прокрутке вниз.

delay()

1
static delay(time: number): CompositeAnimation;

Запускает анимацию после заданной задержки.

sequence()

1
static sequence(animations: CompositeAnimation[]): CompositeAnimation;

Запускает массив анимаций по порядку, ожидая завершения каждой из них перед запуском следующей. Если текущая анимация остановлена, следующие анимации не будут запущены.

parallel()

1
2
3
4
static parallel(
  animations: CompositeAnimation[],
  config?: ParallelConfig
): CompositeAnimation;

Запускает массив анимаций одновременно. По умолчанию, если одна из анимаций остановлена, все они будут остановлены. Вы можете переопределить это с помощью флага stopTogether.

stagger()

1
2
3
4
static stagger(
  time: number,
  animations: CompositeAnimation[]
): CompositeAnimation;

Массив анимаций может выполняться параллельно (накладываться друг на друга), но запускается последовательно с последовательными задержками. Удобно для создания эффектов с задержкой.

loop()

1
2
3
4
static loop(
  animation: CompositeAnimation[],
  config?: LoopAnimationConfig
): CompositeAnimation;

Зацикливает заданную анимацию непрерывно, так что каждый раз, когда она достигает конца, она сбрасывается и начинается снова с начала. Цикл будет выполняться без блокировки потока JS, если для дочерней анимации установлено значение useNativeDriver: true. Кроме того, циклы могут предотвратить отрисовку большего количества строк компонентами на основе VirtualizedList во время работы анимации. Вы можете передать isInteraction: false в конфигурации дочерней анимации, чтобы исправить это.

Config — это объект, который может иметь следующие параметры:

  • iterations: Количество циклов анимации. По умолчанию -1 (бесконечно).

event()

1
2
3
4
static event(
  argMapping: Mapping[],
  config?: EventConfig
): (...args: any[]) => void;

Принимает массив отображений и извлекает значения из каждого arg соответственно, затем вызывает setValue для отображенных выходов. например.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
onScroll={Animated.event(
  [{nativeEvent: {contentOffset: {x: this._scrollX}}}],
  // Optional async listener
  {listener: (event: ScrollEvent) => console.log(event)},
)}
/* ... */
onPanResponderMove: Animated.event(
  [
    null, // raw event arg ignored
    {dx: this._panX},
  ], // gestureState arg
  {
    listener: (
      event: GestureResponderEvent,
      gestureState: PanResponderGestureState
    ) => console.log(event, gestureState),
  } // Optional async listener
);

Config — это объект, который может иметь следующие параметры:

  • listener: Необязательный асинхронный слушатель.
  • useNativeDriver: Использует родной драйвер, если true. Требуется.

forkEvent()

1
static forkEvent(event: AnimatedEvent, listener: Function): AnimatedEvent;

Расширенное императивное API для отслеживания анимированных событий, передаваемых через пропсы. Он позволяет добавить новый javascript-слушатель к существующему AnimatedEvent. Если animatedEvent является javascript-слушателем, он объединит два слушателя в один, а если animatedEvent имеет значение null / undefined, он назначит javascript-слушатель напрямую. Используйте значения напрямую, где это возможно.

unforkEvent()

1
static unforkEvent(event: AnimatedEvent, listener: Function);

start()

1
static start(callback?: (result: {finished: boolean}) => void);

Анимация запускается вызовом start() на вашей анимации. start() принимает обратный вызов завершения, который будет вызван, когда анимация будет завершена или когда анимация будет завершена, потому что stop() был вызван на ней до того, как она смогла завершиться.

Параметры:

Имя Type Обязательно Описание
callback (result: {finished: boolean}) => void Нет Функция, которая будет вызвана после нормального завершения анимации или когда анимация закончилась, потому что перед ее завершением была вызвана функция stop()

Запустите пример с обратным вызовом:

1
2
3
Animated.timing({}).start(({ finished }) => {
    /* completion callback */
});

stop()

1
static stop();

Останавливает любую запущенную анимацию.

reset()

1
static reset();

Останавливает любую запущенную анимацию и возвращает значение к исходному.

Свойства

Value

Стандартный класс значений для анимации движения. Обычно инициализируется с помощью new Animated.Value(0);.

Подробнее об API Animated.Value можно прочитать на отдельной странице.

ValueXY

Класс 2D-значений для управления 2D-анимацией, например, жестами панорамирования.

Подробнее об API Animated.ValueXY можно прочитать на отдельной странице.

Interpolation

Экспортируется для использования типа интерполяции в потоке.

Node

Экспортируется для удобства проверки типов. Все анимированные значения происходят от этого класса.

createAnimatedComponent

Делает любой компонент React анимируемым. Используется для создания Animated.View и т.д.

attachNativeEvent

Императивный API для прикрепления анимированного значения к событию в представлении. Предпочтительно использовать Animated.event с useNativeDriver: true, если это возможно.

Ссылка

Комментарии