Источник: Nuances of Programming
Вы создаете умопомрачительную анимацию с помощью 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 lottie-ios@3.18
Этот этап подготовки пройден, и теперь нам нужны файлы активов.
Файлы активов
Вы можете воспользоваться собственной анимацией, экспортировав ее с помощью плагина 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 отлично подойдет для вашего приложения. И конечно, вы оцените тот факт, что вам не нужно перестраивать анимации посредством кода, вследствие чего можно сосредоточиться на более важных частях проекта.
Читайте также:
Первод статьи Hussain Arif: How To Create Animations With Lottie-React-Native