Как сделать последовательную / параллельную анимацию в React-native-reanimated 2?

Я ищу эквивалент Animated.sequence а также Animated.parallelот react-native. Пока что от документации по v2 я мог видеть только withSequence функция, которая изменяет значение только для значения и, следовательно, стиль только одного компонента в серии.

Я искал запускать анимацию в двух разных компонентах, последовательно или параллельно. Для параллельной работы кажется, что изменение значений в операторах одно за другим сработало. Поправьте меня если я ошибаюсь.

        // these will run in parallel
  val1Shared.value = withTiming(50);
  val2Shared.value = withTiming(100);

Но для серии мне нужно, чтобы каждая анимация была внутри обратного вызова useTiming. Что приводит к аду обратного вызова.

        val1Shared.value = withTiming(50, undefined, () => {
    val2Shared.value = withTiming(100);
  });

Пожалуйста, помогите с лучшими практиками в достижении этого с помощью reanimated 2. Спасибо.

1 ответ

Я думаю, что нет способа сделать это, как в Animated.

Эта библиотека требует, чтобы вы думали по-другому. Если вы хотите запустить две анимации (каждую для отдельного представления) с использованием интерполяции, вы можете использовать одно общее значение и достаточную конфигурацию интерполяции.

Предположим (согласно вашему примеру), что у вас есть два представления, которые вы хотите анимировать. Первая анимация от 0 до 50, вторая от 0 до 100.

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

Инициализируйте общее значение:

      const animation = useSharedValue(0);

И сделайте что-то вроде этого (на ваш выбор):

      animated.value = withTiming(1, { duration, easing });

На первый взгляд ваше преобразование будет выглядеть так:

      const animatedStyles1 = useAnimatedStyle(
() => ({
  transform: [
    {
      translateX: interpolate(animation.value, [0, 0.5, 1], [0, 50, 50]),
    },
  ],
}),
[mode, rectSize]);

а для второго вот так:

      const animatedStyles2 = useAnimatedStyle(
() => ({
  transform: [
    {
      translateX: interpolate(animation.value, [0, 0.5, 1], [0, 0, 100]),
    },
  ],
}),
[mode, rectSize]);

Теперь объяснение.

Для первого вида работаем только на половине прогресса от всей анимации, поэтому от 0 до 0.5 будем анимировать от 0 до 50. потом для сброса прогресса останемся на том же месте ( это называется мертвая зона), от 0,5 до 1 значение прогресса не меняется (от 50 до 50). Теперь, для второго представления, мы ждем, пока прогресс будет вдвое, поэтому от 0 до 0,5 мы ничего не делаем (от 0 до 0). Затем, когда прогресс в два раза, мы анимируем вид от 0 до 150.

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

Здесь вы можете найти больше информации об интерполяции. Документы взяты из Animated, но идея та же.

Удачи!

Другие вопросы по тегам