React Native - способы реализации анимации

Анимация и React

Анимация в React Native – популярная тема для семинаров и занятий, возможно, потому, что многим разработчикам сложно с ней работать. Хотя многие онлайн-блоги и ресурсы посвящены аспектам производительности React Native, лишь немногие знакомят вас с основами. В этой статье я расскажу об основах реализации анимации React Native.

Для работы с кроссплатформенным кодом JavaScript нативные компоненты вашего телефона должны передавать информацию через элемент, называемый мостом. Мост асинхронный, что приводит к задержке приложений React Native на основе JavaScript, поскольку асинхронные запросы по мосту забивают путь кода JavaScript, взаимодействующего с собственными частями.

Для достижения высокой производительности анимации должны отображаться в собственном потоке пользовательского интерфейса. Поскольку данные должны быть сериализованы через мост, это часто блокирует поток JavaScript, вызывая падение кадров. Эта проблема была распространена с 2015 года, когда анимации представляли одно из самых больших ограничений в React Native.

К счастью, с тех пор ситуация улучшилась благодаря подавляющей поддержке со стороны членов сообщества. Достижение 60 кадров в секунду (FPS) теперь распространено для анимации в React Native. Декларативные API, такие как Animated, облегчили процесс реализации интерактивных анимаций.

Использование Animated API для повышения производительности

Тем не менее, разработчики нередко сталкиваются с проблемами производительности, особенно когда они работают над сложной анимацией.

Как упомянуто выше, слабые места производительности в анимациях React Native вызваны большими нагрузками на потоки JavaScript, что снижает частоту кадров и вызывает плохой пользовательский опыт. Чтобы преодолеть эту проблему, вам нужно поддерживать частоту кадров 60 кадров в секунду.

Использование Animated API – лучшее решение для этого, поскольку оно оптимизирует требуемое время сериализации/десериализации. Это делается с помощью декларативного API для описания анимации. Идея заключается в том, чтобы объявить всю анимацию сразу, чтобы можно было сериализовать объявление в JavaScript и отправить его на мост. Затем драйвер выполняет анимацию кадр за кадром.

Как реализовать анимацию в React Native

Есть несколько способов реализовать анимацию в React Native. Вот некоторые из них, которые я считаю наиболее полезными.

Анимированные значения

Анимированные значения возглавляют мой список как строительный блок для анимации в любом приложении React Native. Они обычно указывают на реальное значение, которое преобразуется обратно в реальное число при передаче с анимированным компонентом.

Давайте посмотрим на пример:

В приведенном выше примере я объявил value.ToAnimate как 42, которое будет выполнено через 1000 миллисекунд.

Вы также можете использовать анимированные значения для объявления таких свойств, как непрозрачность или положение. Вот пример реализации прозрачности с анимированными значениями:

Драйверы анимации: Animated.timing, Animated.event, Animated.decay

Представьте, что драйверы похожи на узлы на графике, который изменяет значение анимации с каждым кадром. Например, Animated.timing будет увеличивать значение, а Animated.decay будет уменьшать значение для каждого кадра.

Давайте посмотрим на пример:

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

Вы также можете использовать Animated.event, чтобы ввести значение в качестве пользовательской прокрутки:

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

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

Методы преобразования

Методы преобразования позволяют преобразовать анимированное значение в новое анимированное значение.

Вы можете использовать такие методы, как Animated.add (), Animated.multiply() или Animated.interpolate() для реализации операций преобразования. Вы можете выполнить операцию преобразования на любом узле графика в Animated.

Реквизиты Animated

Реквизиты Animated – это специальные узлы, которые отображают анимированное значение в реквизит компонента. Он генерируется, когда вы визуализируете Animated.view и назначаете ему свойства.

Давайте посмотрим на следующий фрагмент кода:

Здесь я добавил Animated prop, который преобразует значение 0,7 в свойство. Если метод обновляет значение, это изменение будет отражено в свойстве представления.

Описанные выше методы работают совместно с анимационными объектами в React Native и играют важную роль в них.

Анимированное значение для каждого кадра анимации изменяется драйвером анимации (Animated.Timing, Animated.Event или Animated.Decay). Затем результат передается в любую операцию преобразования, где он сохраняется как опора представления (непрозрачность или значение преобразования).

Затем результат передается в собственную область с помощью JavaScript, где представление обновляется при вызове setNativeProps. Наконец, он передается на iOS или Android, где обновляется UIView или Android.View.

Реализация анимации с использованием Animated API и Native Driver

С момента создания React Native Animated API для выполнения фрейма использовался драйвер JavaScript, но это привело к удалению фрейма, поскольку бизнес-логика напрямую попадает в поток JavaScript.

Чтобы решить проблему пропадания кадров, последняя версия драйвера была сделана чисто нативной, и теперь она способна выполнять анимацию покадрово в нативной области.

Native Driver, когда он используется вместе с Animated API, позволяет нативному анимированному модулю обновлять представления напрямую без необходимости вычислять значение в JavaScript.

Чтобы использовать Native Driver, необходимо указать значение true для useNativeDriver при настройке анимации:

Использование PanResponder для обработки жестов в React Native

React Native Animated API может выполнить большую часть «рутинной работы» за вас при реализации анимации React Native. Однако при реализации жестов в анимации у него есть ключевое ограничение: он не может реагировать на жесты, выходящие за рамки ScrollView.

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

В React Native жесты можно легко обрабатывать с помощью PanResponder с Animated API.

PanResponder объединяет различные прикосновения в определенный жест. Это делает одно касание реагировать на дополнительные прикосновения, чтобы жесты функционировали плавно.

По умолчанию PanResponder состоит из дескриптора InteractionManager, который блокирует события, выполняемые в потоке JS, от прерывания жестов.

Улучшение времени работы для медленных переходов Navigator

Любая анимация React Native, которая включает в себя переход с одного экрана приложения на другой, обычно должна выполняться с использованием компонентов навигации. Компоненты навигации, такие как React Navigation, обычно используются для переходов навигации.

В React Native навигационные переходы обычно происходят в потоках JavaScript, что может привести к медленным переходам для устройств с низким уровнем памяти или с малым объемом памяти (как правило, для Android, поскольку устройства iOS обрабатывают их более эффективно). Медленные переходы навигации обычно происходят, когда React Native пытается отобразить новый экран, пока анимация все еще выполняется в фоновом режиме.

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

Наверх
Меню