Skip to content

Instantly share code, notes, and snippets.

@browniefed
Created August 3, 2018 15:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save browniefed/ea2d46b398bd33fd5b741e54e074a0a7 to your computer and use it in GitHub Desktop.
Save browniefed/ea2d46b398bd33fd5b741e54e074a0a7 to your computer and use it in GitHub Desktop.

Intro

The point of React Native is to have your logic inside of JS. Reanimated is purely declarative and native. In order to communicate back you need to use call which is a declared method that you provide a list of animated values and a JavaScript function.

When dealing with the callback it must be bound to this when passed in because things need to be setup at first render. This means you have 2 options. The first is to setup in constructor and do the old bind method. However if you want to still use class property syntax you would need to use componentWillMount which has been deprecated.

Setup

We first need to setup our 2 sides. One side will just be white and blank. Then we'll setup a drop zone at the bottom of the screen.

We'll also create a circle that we will eventually drag.

https://gist.github.com/06b2e5f260437dec1da32d5c8060c126

Setup Dragging

Our dragging is a combination of the current drag position that is held in dragX and dragY. Then we use our offsets to hold onto the combination of all drag differences over time. That way we won't have any jumping when you adjust the dragging circle multiple times.

Then we save off our gestureState so we can compare and know when the gestures start and end. Then we also setup our event that will be passed to our PanGestureHandler.

https://gist.github.com/f9734aa5b24c21421ecd4e8cbfa0ca15

Now we focus on the combination of all the animated values we setup. We do multiple combinations of adding offset to a drag so we save off as addX and addY to save on typing out the same code multiple times.

When we compare our gestureState and our drag is active our addX or addY will run. Once completed and transitions to a non-active state we update our offsets to contain the previous offset as well as the current drag position.

https://gist.github.com/8ba43519853966e4ce9e9a8fb88ebeb6

Now we apply our handler to onGestureEvent and onHandlerStateChange then pass our transX and transY into our transform.

https://gist.github.com/8240785699c98acf5549aaac1489f1bd

The Callback

This is where the callback to the javascript land comes into place. We'll first declare an onDrop function. The onDrop function will receive both the x and the y values.

We need to bind our this.onDrop to the current instance so we do that first. With Reanimated being declarative we must declare a block that will create the appropriate conditions.

In our case we chose the transY and converted the else section of the condition to a block. When the non-active condition is no longer met rather than running just the set we'll run another condition.

In our case we'll pass an array which just tells Reanimated to run both commands and return the last item in the array. So in our case it'll evaluate the second cond but return the combination of offsetY and dragY like we expected.

We'll check that the gestureState is now in the END state as there are multiple non-ACTIVE states. If it is then we execute our call command. Which takes an array of animated values as the first argument and a JS function to call back with those values.

Because of the way Reanimated and React Native Gesture Handler works the additions haven't been flushed through yet. So we can't simply just provide the offsetX and offsetY, and we also can't provide transX or transY as that would be self referential.

The solution here is to provide the 2 add functions we had saved off earlier. This will add up for the current gesture the offset and the drag and provide appropriate values to our onDrop function.

https://gist.github.com/8a0d9342e3142e5f624c76136240be12

Logic

Now comes the logic. We need to get a few things first. We need the drop zone layout so we can know whether or not the circle is in the box or not. We use the onLayout function and provide it a saveDropZone function.

We destructure the layout object and do a little math to save off the drop zone top/bottom/left/right locations.

https://gist.github.com/701bfd43691edc294c78600dde07edda

With the drop zone information saved off we can then compare that to the x and y that gets provided to the onDrop. Here we make sure the x is in between the left/right, and then we make sure the y is in between the top and bottom of our drop zone.

If it is then we know that the circle has moved into the drop zone and we can alert.

https://gist.github.com/925c545cd65c32d159aad3b748df0e3c

Ending

Reanimated provides mechanisms to keep your animations purely native and only talk back to the JavaScript world when necessary. This is a different approach to Animated that will always talk back and forth regardless of whether you want to or not.

This provides the most effect way to have performant animations and still execute JavaScript logic whenever is necessary.

Live Demo Here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment