Перевод статьи подготовлен специально для студентов курса «ReactJS/React Native-разработчик».
Трудно себе представить мобильное приложение, в котором нет анимации. В вебе анимации обычно простые, если они есть вообще (максимум – одна страница сменяет другую). Анимации же в мобильных приложениях требуют к себе совсем другого внимания.
У CSS3 есть относительно простой API, который позволяет делать несложные анимации. Но в React Native у вас нет этого инструмента. Да если бы и был, то его было бы недостаточно.
Итак, что вам нужно знать, если вы работаете с React Native и вам нужно реализовать полноценные анимации?
В React Native есть такой инструмент, как Animated, но он выглядит устрашающе… по крайней мере поначалу.
Итак, есть три «группы вещей» или «блока», если хотите, о которых вам нужно знать, чтобы работать с анимацией.
Блок 0: Необходимость перемен
Анимации представляют собой изменение одного состояния на другое:
- Переход из «скрытого» в «видимое»;
- Переход от круга к квадрату.
Подумайте о том, что нужно показывать до и после анимации.
Подумайте над переходами и над тем, какие стили нужно для этого изменить:
- Должен ли объект появиться с изменением прозрачности или он должен просто «упасть» сверху?
- Должен ли круг просто превратиться в квадрат, или он должен стать треугольником в середине процесса?
Блок 1: Визуальное состояние, известное как Animated.Value
С логической точки зрения любой компонент может быть либо показан, либо скрыт – это значения «истина» и «ложь», среднего тут не существует. В виде состояния, отображение того, показан ли объект будет либо истинным, либо ложным.
В хорошем пользовательском интерфейсе объекты не скрываются внезапно и также внезапно не появляются. Они проявляются постепенно, помогая пользователю разобраться в интерфейсе.
Таким образом, становится ясно, что визуальное состояние может быть чем-то между истинным состоянием и ложным.
Как же так?
Мы можем ввести еще одну переменную для представления диапазона визуального состояния. Нам нужно, чтобы это было число, поскольку независимо от того, какое мы имеем логическое состояние, числа помогают нам представлять промежуточные значения.
this._shown = new Animated.Value(0);
В то время как логическое состояние может быть двоичным (т.е. либо true
, либо false
, 1 или 0), визуальное состояние – это число с плавающей точкой.
Блок 2: Переходы, известные как Animated.timing
Скажем, какой-либо компонент скрыт: это значит, что логическое состояние его параметров видимости будет ложным, и визуальное состояние будет также 0.0. Но что происходит, когда мы хотим показать компонент? Логическое состояние должно немедленно стать истинным, тогда как визуальное состояние должно постепенно переходить сначала в 0.1, 0.2, … и наконец полностью в 1.0.
Для этого нам нужен способ сообщить визуальному состоянию переход к 1.0.
И такие способы есть. Вообще-то их даже несколько.
Самый простой способ это в основном:
Animated.timing(this._shown, {
toValue: 1,
duration: 300,
}).start();
Здесь, мы говорим Animated
изменять _shown
до 1.0
в промежутке 300 мс.
Есть и другие переходы, и способы организовать несколько переходов, но сейчас мы вполне можем использовать Animated.timing
.
Блок 3: Пиксели, известные как Animated.View
и interpolate
Наши переходы _shown
между 0.0
и 1.0
ничего не значат, если мы их не можем увидеть. Так как же нам это сделать?
Нам нужно каким-то образом использовать _shown
для установки степени прозрачности дочернего компонента.
Предположим, до начала работы с анимациями у нас был вот такой код:
<View style={{ opacity: this.state.shown ? 1 : 0 }}>
<SomeComponent />
</View>
Мы устанавливаем прозрачность в 0
, когда скрываем компонент и в 1
, когда показываем.
Можем ли мы использовать имеющееся Animated.Value
и _shown
, чтобы анимировать переход от 0
к 1
?
Анимация стилей
Мы можем использовать любое Animated.Value
, когда работаем со стилями.
Нам нужно всего лишь изменить View
на Animated.View
, и теперь у нас есть следующее:
const opacity = this._shown; // This is an Animated.Value
<Animated.View style={{ opacity: opacity }}>
<SomeComponent />
</Animated.View>
Разве это не статья про анимации? Почему до сих пор не было картинок?
Еще одна вещь: интерполяция
Это слово звучит страшно, но сама идея довольно проста. Интерполяция позволяет нам сохранить визуальное состояние в рамках 0 и 1, но давать возможность «сопоставления» чему-то еще.
Скажем, вместо того чтобы просто создавать компонент-наследника, мы хотим, чтобы сам наш компонент «выпадал сверху». И мы можем это сделать, поставив скрытый компонент на 40px выше, и анимируем его передвижение к желаемой позиции, во время изменения состояния на видимое.
Мы можем «сопоставить» наши значения от 0 до 1 со значениями от -40 до 0, используя обычный вызов interpolate
:
const top = this._shown.interpolate({
inputRange: [0, 1],
outputRange: [-40, 0],
});
Это создаст новое Animated.Value
, значение которого будет от -40 до 0.
Другими словами, оно будет -40
, когда _shown
равно 0
, -20
– при _shown
=0.5
и 0
при _shown
равному 1.0
.
Темная тайна: с помощью interpolate
вы можете также менять значения для цветов и градусов.
Выводы:
- Визуальное состояние – это числовое значение, оно должно отражать переход от одного стиля к другому.
Animated.Value
позволяет отражать числовое значение визуального состояния.Animated.timing
можно использовать для переходаAnimated.Value
в другое число.Animated.Value
может быть использовано для стилей, при заменеView
наAnimated.View
.
Интерполяция позволяет сопоставлять один диапазон Animated.Value
другому, например диапазон от 0
до 1
к диапазону от 5
до 25
или даже к диапазону между черным и зеленым.
Источники:
В этой статье мы познакомились с примитивами анимации в React Native и получили понимание об основной идее. Вот здесь вы можете найти ресурсы, которые помогут изучить эту тему глубже:
- Фантастический курс на Egghead от Джейсона Брауна «Animate React Native UI Elements» – лучший из лучших;
- Официальная документация React Native по анимациям;
- Официальная документация Animated;
- Моя статья про анимированное появление и исчезновение с помощью React Native;
- Статья про анимированное поле ввода;
- 4 места для поиска вдохновения для практики React Native.
Автор: MaxRokatansky