Rive-анимация для Flutter-приложений: почему мы любим ее больше Lottie, когда ее применять и какие фишки использовать

от автора

Привет! Меня зовут Никита Грибков, я Flutter-разработчик в AGIMA. Расскажу вам про возможности Rive — фреймворка, который использует векторную графику для создания анимации во Flutter-приложениях. Эта статья выросла из небольшого поста на Хабре, в котором я коротко описал опыт работы над кнопкой для Bottom Bar в своем пет-проекте. Здесь же я уже подробно опишу, как анимировать элементы и чем вообще хорош Rive.

Почему Rive

Когда я впервые столкнулся с необходимостью добавить анимацию во Flutter-приложение, выбор, само собой, пал на Lottie. Это вид анимации, который тогда пользовался популярностью. И хотя внедрить его в проект было непросто, кастомный лоадер был установлен. И надо отдать ему должное — он отлично работал.

Однако вскоре алгоритмы Google подкинули мне информацию о RIve. Это еще один формат анимации, который, как оказалось, намного больше подходил под наши бизнес-задачи. И самые убедительные аргументы тому мы нашли прямо в документации Rive:

Пример веб-сайта Lottie

Пример веб-сайта Rive

Размер файла: 181,7 КБ (без сжатия)

Память графического процессора: 149–190 МБ

Куча JS: 16,9 МБ

ЦП: 91,8%

Размер файла: 18 КБ (без сжатия)

Память графического процессора: 2,6 МБ

Куча JS: 7,3 МБ

ЦП: 31,8%

Как видим, создатели Rive позаботились о том, чтобы анимация была легче и быстрее. Мы с командой прикрутили Rive-лоадер, и вскоре поняли, что управлять анимацией стало в разы проще, а User-flow стал удобнее. Ниже рассказываю про основные инструменты Rive, а в конце объясню, в каких случаях его лучше всего применять.

Преимущества Rive

При разработке Flutter-приложений вообще используют много типов анимации, мы уже писали об этом в отдельной статье. Но на мой взгляд, Rive превосходит большинство из них. Во-первых, мне нравится встроенный UI-интерфейс. Во-вторых, в Rive есть раздел Community, где авторы выкладывают бесплатные анимации.

А в-третьих, — и это главное преимущество — в Rive есть State Machine. Это визуальный способ связать анимацию воедино и определить логику, которая управляет переходами. State Machine позволяет создавать интерактивную графику движения, готовую к внедрению в ваш продукт, приложение, игру или веб-сайт.

State Machine включает несколько уровней:

  • Graph (График) — это пространство, в котором мы будем добавлять состояния и соединять переходы. Он появляется вместо временной шкалы, когда машина состояний выбрана в списке анимаций.

  • State — это просто анимации временной шкалы, которые могут воспроизводиться в нашей машине состояний. Как правило, они представляют собой некоторое состояние, в котором находится ваш анимированный контент.

  • Transaction — переходы представляют собой логическую карту для State Machine. Существует ряд соображений и настраиваемых свойств для переходов.

  • Inputs — это договор между дизайнерами и разработчиками. Как дизайнеры, мы используем входы как способ управления переходами в нашей машине состояний, назначая их в качестве условий. Разработчики связываются с входами во время выполнения и определяют условия с помощью кода, который может изменить эти входы.

  • Layers — слой State Machine, который позволяет воспроизводить одну анимацию за раз. По этой причине вы можете создать несколько слоев, если хотите смешать несколько анимаций или добавить дополнительные взаимодействия в State Machine.

Инструменты Rive

Для работы с Rive Animation лучше использовать их UI-интерфейс, в котором и происходит создание и настройка самой анимации. Анимация состоит из нескольких составляющих. Они больше знакомы дизайнерам, но, если кратко, вот некоторые из них.

  1. Artboard: слой, который является холстом анимации на котором располагаются остальные элементы. В нем можно задать цвет и размер фона. В каждом файле Rive есть хотя бы один такой.

  2. Group: необязательный элемент, но он отлично подходит, чтобы объединить элементы в группы для любого объекта, изменение которого может потребоваться в дальнейшем.

  3. Shape: Rive позволяет создавать, редактировать и анимировать векторную графику, используя процедурные или пользовательские фигуры. Из них чаще всего и состоит весь интерфейс. Также есть крутой инструмент Pen.

  4. Pen: это инструмент, который позволяет делать очень сложные кастомные фигуры. 

Три вида операторов, которые используются для триггера анимации

Number

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

Допустим, у нас есть анимация загрузки, которая активируется, когда счетчик достигает определенного значения. Для начала создаем контроллер и каунтер:

RiveAnimationController _controller;  int _counter = 0;

Затем создаем метод, в котором будем обрабатывать состояние в зависимости от значение _counter.

void _incrementCounter() {     setState(() {         _counter++;         if (_counter >= 10) {             _controller = SimpleAnimation('loading');         } else {             _controller = SimpleAnimation('idle');         }     }); }

После этого создаем контейнер с нашим ассетом и добавляем ElevatedButton с методов _incrementCounter.

Column(     mainAxisAlignment: MainAxisAlignment.center,     children: [         SizedBox(             width: 200,             height: 200,             child: RiveAnimation.asset(                 'assets/loading_animation.riv',                 controllers: [_controller],                 fit: BoxFit.cover,             ),         ),         ElevatedButton(             onPressed: _incrementCounter,             child: Text('Increment Counter: $_counter'),         ),     ], ),

Bool

Каждый разработчик знает об этом операторе. Он может быть True или False. В зависимости от значения логического оператора обрабатывает логику анимации.

Для Bool-оператора всё тривиально. Думаю, комментарии тут излишни. Так бы выглядел код всё с тем же лоадингом:

RiveAnimationController _controller; bool _isPlaying = false;  void _toggleAnimation() {     setState(() {         _isPlaying = !_isPlaying;         if (_isPlaying) {             _controller = SimpleAnimation('play');         } else {             _controller = SimpleAnimation('idle');         }     }); }
Column(     mainAxisAlignment: MainAxisAlignment.center,     children: [         SizedBox(             width: 200,             height: 200,             child: RiveAnimation.asset(                 'assets/toggle_animation.riv',                 controllers: [_controller],                 fit: BoxFit.cover,             ),         ),         ElevatedButton(             onPressed: _toggleAnimation,             child: Text(_isPlaying ? 'Pause' : 'Play'),         ),     ], ),

Trigger

Триггеры аналогичны логическим значениям, но могут стать истинными только на короткое время.

С триггером мы получаем чуть больше кода, так как триггеры могут быть заданы разные и надо их обрабатывать из самого ассета. 

 Artboard _artboard;  RiveAnimationController _controller;   void _triggerAnimation() {      if (_controller != null) {          _artboard.artboard.removeController(_controller);      }      _controller = SimpleAnimation('trigger');      _artboard.artboard.addController(_controller);  }
@override void initState() {     super.initState();     _rootBundle(); } void _rootBundle() {     rootBundle.load('assets/trigger_animation.riv').then((data) {         final file = RiveFile.import(data);         final artboard = file.mainArtboard..addController(SimpleAnimation('idle'));         setState(() => _artboard = artboard);     }); }
Column(     mainAxisAlignment: MainAxisAlignment.center,     children: [         _artboard != null ?         Rive(             artboard: _artboard,             fit: BoxFit.cover,         ) :         SizedBox(),         ElevatedButton(             onPressed: _triggerAnimation,             child: Text('Trigger Animation'),         ),     ], ),

Вывод

В итоге Rive-анимацией мы закрыли все кейсы, когда в приложении заказчика нужно было проигрывать анимацию. Сейчас Rive в наших проектах используется повсеместно как основной инструмент анимации. Хотя и про Lottie мы иногда вспоминаем.

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

  • Lottie лучше использовать, если вам нужны простые и легкие анимации, которые легко интегрировать в многоплатформенные приложения.

Если у вас остались вопросы про Rive — буду рад ответить в комментариях. Также подписывайтесь на канал нашего руководителя направления мобильной разработки Саши Ворожищева — у него много про Flutter.

Что еще почитать


ссылка на оригинал статьи https://habr.com/ru/articles/827732/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *