Смысл 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.

Подпишитесь на нашу Информационную рассылку, чтобы получать самую свежую и лучшую информацию, которая сделает вас лучшим разработчиком.

Если этот пост был полезен, пожалуйста, нажмите несколько раз кнопку хлопка 👏 ниже, чтобы выразить свою поддержку! ⬇⬇