This lesson is for PRO members.

Unlock this lesson NOW!
Already subscribed? sign in

Create a Draggable Card with React Native Pan Responder, and Animated.decay

3:57 React lesson by

In this lesson we'll create a PanResponder to allow us to drag a card around the screen. We'll use Animated.event to automatically set the values of our Animated.Value and when the card is released we'll use Animated.decay to decelerate it to a stop.

Get the Code Now
click to level up

egghead.io comment guidelines

Avatar
egghead.io

In this lesson we'll create a PanResponder to allow us to drag a card around the screen. We'll use Animated.event to automatically set the values of our Animated.Value and when the card is released we'll use Animated.decay to decelerate it to a stop.

Avatar
peekpic

getting 404 on the github link

Avatar
Jason Brown

Apologies for that, I accidentally named it animated_decay instead of just decay.
I've fixed the link and it should have the proper code.

In reply to peekpic

We'll start by importing Animated and PanResponder from React Native. Next, we'll create a componentWillMount lifecycle method, then type this._panResponder is equal to the PanResponder that we create.

This PanResponder will then give us panHandlers, which we can then spread this.panResponder.panHandlers onto the view that we want to attach touch events to. Now we'll go create our animated value by typing this.animatedValue = new Animated.ValueXY.

Next, we'll replace our onPanResponderMove with Animated.event, which is a function that takes an array. Animated will then traverse all of the arguments and assign those arguments to our animated values that we pass in. We'll ignore the first event.

We'll map the delta x, the change in the X location, to this.animatedValue.x and the delta y to this.animatedValue.y. Next we'll switch our view from a regular view to an animated view. Then we'll create const Animated.style, which is an object.

We'll say transform: this._animatedValue.getTranslateTransform, which is a helper function to return our TranslateTransform. Then we'll attach that to our animated view. Now, when we refresh our emulator, we can drag the square around the screen.

However, if I drop it and then try to drag it again, the animated value will be set to the delta of the new touch, which will cause the square to jump. Because we're dealing with the delta of the drag, we need to attach a listener by saying this._animatedValue.addListener, which is a function that takes a function.

The first argument is value. Then we'll assign it to this.value=value. We'll set up our default at this.value = {x: 0, y: 0}. In our PanResponderGrant, we'll say this.animatedValue.setOffset({x: this.value.x, y: this._value.y}).

Additionally, we'll set this._animatedValue.setValue({x: 0, y: 0}) to clear out our animation. Now when we refresh our emulator, we can drag the square across the screen, drop it, and then pick it up, and drag it again.

In our onPanResponderRelease, which is when we release our touch, we'll say this._animatedValue.flattenOffset, which will flatten our offset delta into our animated value to prepare us for another drag.

Then we'll use Animated.decay, which is a function that takes this._animatedValue and a configuration object. It takes a deceleration, which we'll say is 0.997. Then we'll give it the velocity of our final touch, which is an object that takes an X direction which it can get from gestureState.vx and our y from gestureState.vy.

Now, we'll call start on our animation. If we refresh our emulator, we can drag our square across the screen. Then we release it. It will decay its acceleration in the direction that we released it.

HEY, QUICK QUESTION!
Joel's Head
Why are we asking?