Анимация для React DOM · API Animated из React Native

Опишите движение один раз. Оно плавное и никогда не ломается.

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

Установка
npm install @kkwaenggwari/animated

Одно значение часов управляет рябью всех 64 фигур. Проведите указателем по сцене.

Измерено на этом релизе

Измерено на сборке 1.0.0 в headless Chrome на настольном PC. Цифры зависят от устройства. Как мы измеряли

  • 0.00msJavaScript за кадр, пока движутся 400 элементов

    Конечное движение transform и opacity на элементах Animated воспроизводит браузер. Собственные колбэки кадров страницы не выполняют работы.

  • 0.13msJavaScript за кадр, когда одно значение управляет 10 000 элементов

    Значение записывает одну CSS-переменную; каждый элемент выводит из неё свой стиль средствами CSS.

  • 0Рендеры React во время движения

    Значения никогда не проходят через состояние React. Компоненты перерисовываются, когда меняются ваши props, а не когда меняется кадр.

01 · Просто

Знакомый API на обычном style React

timing, spring, interpolate, loop и Animated.event сохраняют имена и конфигурации React Native. Значение передаётся прямо в обычный проп style, поэтому до первого движения не нужно изучать никаких особых компонентов.

  • Перенесите код из React Native, переименовав Animated.View в Animated.div.
  • Одно значение может одновременно двигать полосу, циферблат и ряд карточек — каждый со своим диапазоном.
  • useAnimated владеет рецептом: запускается при монтировании, перезапускается при изменении зависимости и убирает за собой при размонтировании.

Подготовка примера…

Те же вызовы, что в React Native

Spinner.jsx
// React Native
<Animated.View style={{ transform: [{ rotate }] }} />

// React DOM with @kkwaenggwari/animated — the rest is identical
<Animated.div style={{ transform: [{ rotate }] }} />

const spin = useAnimatedValue(0);
const rotate = spin.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] });

Animated.loop(
  Animated.timing(spin, { toValue: 1, duration: 900, easing: Easing.linear, useNativeDriver: true }),
).start();

02 · Быстро

Без рендера React на каждый кадр

Значение хука — это CSS-переменная. Линейные интерполяции и арифметика становятся точными выражениями calc() от этой переменной, поэтому каждый кадр — одна запись, а остальное вычисляет браузер. Конечное движение transform и opacity на элементах Animated.<tag> воспроизводит браузер без колбэков кадров.

  • Измените число точек: счётчик показывает, что React отрисовал один раз на изменение, а не на кадр.
  • scope записывает значение один раз в контейнер, а не в каждый элемент.
  • inspect(element) сообщает, какой путь использует каждое свойство и почему.

Подготовка примера…

03 · Надёжно

Прерывайте где угодно. Движение продолжится.

Новая цель стартует с того места, где элемент находится на экране, а пружина ещё и сохраняет скорость, поэтому разворот на полпути плавный, без остановки. Контроллеры, объявленные в хуке, останавливаются и освобождаются при замене и размонтировании, а разметка, отрисованная на сервере, продолжает анимироваться после гидратации.

  • Быстро нажмите дважды: со spring траектория изгибается, с timing позиция сохраняется, но начинается новая кривая.
  • Остановка оставляет значение на месте; ничто не прыгает в конечное состояние.
  • Никаких забытых циклов кадров после размонтирования, смены маршрута или скрытой вкладки.

Подготовка примера…

Построено на Animated

Нужен готовый компонент? Animated Chorus.

Прокручивающиеся числа, перемещающаяся подсветка вкладок, прогресс, шторки и анимированные списки, которые сразу встраиваются в React и React Native. Эти три работают на этой странице прямо сейчас.

Перейти в Animated Chorus

Начните за три минуты

Установите пакет, сдвиньте первое значение, а затем выберите руководство для своей задачи.

npm install @kkwaenggwari/animated

Поиск

Начните вводить, чтобы искать в документации.