Смысл React Native в том, чтобы ваша логика находилась внутри JS. Reanimated является чисто декларативным и нативным. Для обратной связи вам необходимо использовать call
, который является объявленным методом, который вы предоставляете список анимированных значений и функцию JavaScript.
При работе с обратным вызовом он должен быть привязан к this
при передаче, потому что все должно быть настроено при первом рендеринге. Это означает, что у вас есть 2 варианта. Первый - настроить в конструкторе и использовать старый метод bind
. Однако, если вы хотите по-прежнему использовать синтаксис свойств класса, вам нужно будет использовать componentWillMount
, который устарел.
Настраивать
Сначала нам нужно настроить наши 2 стороны. Одна сторона будет просто белой и пустой. Затем мы настроим зону перетаскивания внизу экрана.
Мы также создадим круг, который в конечном итоге перетащим.
Настройка перетаскивания
Наше перетаскивание - это комбинация текущей позиции перетаскивания, удерживаемой в dragX
и dragY
. Затем мы используем наши смещения, чтобы удерживать комбинацию всех различий перетаскивания с течением времени. Таким образом, у нас не будет никаких прыжков, если вы несколько раз отрегулируете круг перетаскивания.
Затем мы сохраняем наш gestureState
, чтобы мы могли сравнить и узнать, когда жесты начинаются и заканчиваются. Затем мы также настраиваем наш event
, который будет передан нашему PanGestureHandler
.
Теперь мы сосредотачиваемся на сочетании всех настроенных нами анимированных значений. Мы выполняем несколько комбинаций добавления offset
к drag
, поэтому мы сохраняем как addX
и addY
, чтобы сэкономить на вводе одного и того же кода несколько раз.
Когда мы сравниваем наш gestureState
и наше перетаскивание активно, наши addX
или addY
будут работать. После завершения и перехода в неактивное состояние мы обновляем наши смещения, чтобы они содержали предыдущее смещение, а также текущую позицию перетаскивания.
Теперь мы применяем наш обработчик к onGestureEvent
и onHandlerStateChange
, затем передаем наши transX
и transY
в наше преобразование.
Обратный звонок
Здесь и возникает обратный вызов в страну javascript. Сначала мы объявим onDrop
функцию. Функция onDrop
получит значения как x, так и y.
Нам нужно привязать наш this.onDrop
к текущему экземпляру, поэтому мы делаем это в первую очередь. Поскольку Reanimated декларативен, мы должны объявить блок, который создаст соответствующие условия.
В нашем случае мы выбрали transY
и преобразовали раздел else
условия в блок. Когда неактивное условие больше не выполняется, вместо выполнения только set
мы выполним другое условие.
В нашем случае мы передадим массив, который просто сообщает Reanimated выполнить обе команды и вернуть последний элемент в массиве. В нашем случае он оценит второй cond
, но вернет комбинацию offsetY
и dragY
, как мы и ожидали.
Мы проверим, что gestureState
теперь находится в состоянии END
, поскольку есть несколько состояний, отличных от ACTIVE
. Если это так, мы выполняем нашу call
команду. Которая принимает массив анимированных значений в качестве первого аргумента и функцию JS для обратного вызова с этими значениями.
Из-за того, как работает Reanimated и React Native Gesture Handler, дополнения еще не прошли процедуру очистки. Таким образом, мы не можем просто предоставить offsetX
и offsetY
, и мы также не можем предоставить transX
или transY
, поскольку это будет относиться к себе.
Решение здесь состоит в том, чтобы предоставить 2 функции добавления, которые мы сохранили ранее. Это добавит для текущего жеста смещение и перетаскивание и предоставит соответствующие значения нашей функции onDrop
.
Логика
Теперь пришла логика. Сначала нам нужно кое-что понять. Нам нужен макет зоны перетаскивания, чтобы мы могли знать, находится ли круг в поле или нет. Мы используем функцию onLayout
и предоставляем ей функцию saveDropZone
.
Мы деструктурируем объект макета и делаем небольшую математику, чтобы сохранить верхнее / нижнее / левое / правое положение области перетаскивания.
После сохранения информации о зоне перетаскивания мы можем сравнить ее с x
и y
, которые предоставляются onDrop
. Здесь мы убеждаемся, что x находится между левым и правым, а затем мы убеждаемся, что y
находится между верхом и низом нашей зоны перетаскивания.
Если это так, то мы знаем, что круг переместился в зону сброса, и можем предупредить об этом.
Конец
Reanimated предоставляет механизмы, позволяющие сохранять ваши анимации чисто нативными и разговаривать с миром JavaScript только тогда, когда это необходимо. Это другой подход к Animated, который всегда будет говорить туда-сюда, независимо от того, хотите вы этого или нет.
Это обеспечивает наиболее эффективный способ создания эффективных анимаций и выполнения логики JavaScript всякий раз, когда это необходимо.
Изначально опубликовано в Code Daily.
Заключительные примечания:
Я еженедельно публикую статьи и скринкасты на React, React Native и все остальное, что связано с веб-разработкой, на Code Daily. Обязательно подпишитесь на меня в Twitter.
Подпишитесь на нашу Информационную рассылку, чтобы получать самую свежую и лучшую информацию, которая сделает вас лучшим разработчиком.