Вы создаете умопомрачительную анимацию с помощью After Effects и намереваетесь явить ее миру. Один из способов воплотить задуманное — использовать ее в качестве экрана-заставки или компонента загрузчика в приложении. Но на вашем пути возникает небольшая проблема: Adobe не разрешает это сделать.
И тут на помощь приходит библиотека lottie-react-native, позволяющая отрисовывать анимации в приложении React Native. А самое главное преимущество состоит в том, что для начала работы достаточно лишь минимального объема кода.
На основе материала статьи вы научитесь интегрировать библиотеку lottie-react-native в свой проект. Наша конечная цель выглядит так:
С задачами определились — за дело!
Начальные этапы
Инициализация проекта
В текущем проекте используется Expo. Инициализируем приложение React Native, выполняя в терминале следующую команду:
expo init lottie-tutorial
Установка зависимостей
Требуемые модули:
lottie-react-native
— для создания анимации;lottie-ios
— вложенная зависимость (peer dependency) для отрисовки графики на iOS.
npm install lottie-react-native [email protected]
Этот этап подготовки пройден, и теперь нам нужны файлы активов.
Файлы активов
Вы можете воспользоваться собственной анимацией, экспортировав ее с помощью плагина Bodymovin. Но в данном руководстве мы поработаем с директорией Lottie Files. Она содержит множество бесплатной анимации, которую можно импортировать в проект. Нам интересны две из них: Lava Preloader и Switch Toggle.
Для получения этих активов скачиваем необходимые файлы в формате JSON:
Затем переносим файлы JSON в каталог assets
.
Lottie: основы
В этом разделе вы узнаете об основных принципах этой технологии.
Простые анимации
Создаем файл SimpleAnimation.js
, в котором пишем следующий код:
import React from "react";
import { StyleSheet, View } from "react-native";
import LottieView from "lottie-react-native";
export default function SimpleAnimation() {
return (
<View>
<LottieView
source={require("./assets/67313-lava-preloader.json")}
style={styles.animation}
/>
</View>
);
}
const styles = StyleSheet.create({
animation: {
width: 100,
height: 100,
},
});
- Строка 9. Компонент
LottieView
предназначен для отрисовки анимации. - Строка 10. Свойство
source
указывает Lottie на расположение актива, подлежащего отрисовке. - Строки 18-19. Высота
height
и ширинаwidth
анимации равняются100
единицам.
Теперь осталось только отобразить этот компонент на экране. Для этого в App.js
пишем код:
export default function App() {
return (
<View style={styles.container}>
<SimpleAnimation />
</View>
);
}
Получаем результат:
Объект статичен, поскольку его воспроизведение еще не задано. Приведем его в движение посредством свойства autoPlay
:
<LottieView
source={require("./assets/67313-lava-preloader.json")}
autoPlay
/* дальнейший код.. */
Полученный результат:
Вот так все просто!
Анимации загрузчика
В этом разделе воспользуемся Coffee API для отображения данных на экране. В процессе их загрузки React Native займется отрисовкой анимации.
Создаем файл LoadingAnimation.js
и для начала пишем в нем следующий код:
export default function LoadingAnimation() {
const [data, setData] = useState(null);
const fetchData = async () => {
const resp = await fetch("https://api.sampleapis.com/coffee/hot");
const data = await resp.json();
setData(data);
};
useEffect(() => {
fetchData();
}, []);
const Item = ({ title }) => (
<View style={styles.item}>
<Text>{title}</Text>
</View>
);
- Строки 4–8. Получаем данные из API и сохраняем их в хуке
data
. - Строки 14–18. Компонент
Item
отвечает за отрисовку каждого элемента списка.
Далее добавляем к этому же файлу следующий код:
const renderItem = ({ item }) => <Item title={item.title} />;
<SafeAreaView>
{data ? (
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}
/>
) : (
<LottieView
source={require("./assets/67313-lava-preloader.json")}
style={{ width: 100, height: 100 }}
autoPlay
loop
/>
)}
</SafeAreaView>
);
}
const styles = StyleSheet.create({
item: {
backgroundColor: "yellow",
padding: 20,
marginVertical: 8,
},
});
- Строка 3. Проверяем, загружены ли данные (значение данных не равно
null
). - Строки 4–8. Отображаем массив
data
с помощью элементаFlatList
. - Строки 10–15. Если же данные еще загружаются, отображаем анимацию загрузки.
Получаем результат:
Отлично! Код работает. Далее научимся управлять другими свойствами анимации.
Управление скоростью
Для изменения скорости требуется свойство speed
.
<LottieView
speed={3}
//дальнейший код..
Скорость анимации увеличивается втрое.
Уменьшим скорость, установив отрицательное значение:
<LottieView
speed={3}
//дальнейший код..
Обработка завершения анимации
Lottie содержит свойство onAnimationFinish
. Напишем функцию обратного вызова, которая будет выполняться по завершении анимации.
const [finish, setFinish] = useState(false);
const handleFinish = () => {
setFinish(true);
};
return (
<View>
<LottieView
source={require("./assets/67313-lava-preloader.json")}
style={styles.animation}
onAnimationFinish={() => handleFinish()}
autoPlay
loop={false}
/>
<Text>{finish ? "Finished" : "Running.."}</Text>
</View>
);
- Строка 11. По завершении анимации вызываем метод
handleFinish
, вследствие чего для хукаfinish
устанавливается значениеtrue
. - Строка 13. Устанавливаем для свойства
loop
значениеfalse
, в результате чего Lottie выполняет анимацию только один раз. - Строка 16. Применяем условный рендеринг, чтобы указать на завершение анимации.
Взаимодействие с анимацией
В этом разделе вы узнаете об императивном API Lottie, обеспечивающим более детальное управление активом.
Воспроизведение и пауза
Проинструктируем Lottie запускать анимацию при нажатии пальцем на графические объекты и приостанавливать ее при его поднятии.
Создаем файл InteractiveAnimation.js
, где пишем следующий код:
import React, { useRef, useState } from "react";
import { StyleSheet, View, Pressable, Text } from "react-native";
import LottieView from "lottie-react-native";
export default function InteractiveAnimation() {
const animation = useRef(null);
const [pressed, setPressed] = useState(false);
return (
<View>
<Pressable
onPressIn={() => {
animation.current.resume();
setPressed(true);
}}
onPressOut={() => {
animation.current.pause();
setPressed(false);
}}
>
<LottieView
ref={animation}
source={require("./assets/67313-lava-preloader.json")}
style={styles.animation}
/>
</Pressable>
<Text>{pressed ? "Pressed" : "Not pressed"}</Text>
</View>
);
}
const styles = StyleSheet.create({
animation: {
width: 100,
height: 100,
},
});
Разберем данный код.
- Строка 7. Создаем экземпляр
useRef
для управления анимацией. - Строка 11. Отрисовываем компонент
Pressable
, фиксирующий взаимодействия пользователя. - Строки 12–15. Если палец пользователя на экране (
onPressIn
), возобновляем анимацию. - Строки 16–19. Если пользователь поднял палец (
onPressOut
), останавливаем анимацию. - Строка 22. Связываем хук
animation
с этим экземпляромLottieView
.
Получаем результат:
Переключатели
В этом разделе применим анимацию переключателя для перехода между состояниями “on” и “off”.
Перед тем как продолжить, изучим файл. Обратите внимание, что графика переходит в положение “on” на Frame 27
и возвращается в “off” на Frame 51
.
Наша задача — переключаться между этими кадрами в зависимости от состояния.
Создаем файл SwitchAnimation.js
, в котором пишем следующий код:
import React, { useEffect, useRef, useState } from "react";
import { StyleSheet, View, Pressable, Text } from "react-native";
import LottieView from "lottie-react-native";
export default function SwitchAnimation() {
const animation = useRef(null);
const [on, setOn] = useState(true);
useEffect(() => {
if (!on) {
animation.current.play(0, 27);
} else {
animation.current.play(27, 51);
}
}, [on]);
- Строка 6. Создаем хук
animation
для получения доступа к функциям управления анимацией. - Строка 10. Если состояние не является
on
, воспроизводим анимацию доFrame 27
, что переводит переключатель в состояние “off”. - Строка 12. В противном случае воспроизводим анимацию с
Frame 27
поFrame 51
, вследствие чего переключатель переходит в состояние “on”.
Выполнив эту часть задания, добавляем следующий код:
return (
<View>
<Pressable onPress={() => setOn((old) => !old)}>
<LottieView
ref={animation}
source={require("./assets/67255-switch-toggle.json")}
style={styles.animation}
loop={false}
autoPlay={false}
/>
</Pressable>
<Text> {on ? "On" : "Off"}</Text>
</View>
);
}
const styles = StyleSheet.create({
animation: {
width: 100,
height: 100,
},
});
- Строка 3. При нажатии значение хука
on
меняется на противоположное.
Полученный результат:
Миссия выполнена!
Весь код можно найти на GitHub.
Заключение
Если вы ищите простую в использовании библиотеку анимации, то Lottie отлично подойдет для вашего приложения. И конечно, вы оцените тот факт, что вам не нужно перестраивать анимации посредством кода, вследствие чего можно сосредоточиться на более важных частях проекта.
Читайте также:
- Почему React негативно повлиял на веб-разработку
- Внутренняя жизнь React Native
- 5 проектов на React для начинающих
Читайте нас в Telegram, VK и Яндекс.Дзен
Первод статьи Hussain Arif: How To Create Animations With Lottie-React-Native