React Native tips — Using Animated and PanResponder components to interact with user gestures

Leonardo Bruno Lima
4 min readAug 29, 2018

--

Photo by Brooke Lark on Unsplash

Hi guys! One of the most important thing in a mobile app is understand and interact with user gestures. In React Native we have many ways to do this, but I will show in this post a component call PanResponder that is responsible for track user gestures and once a gesture is detected I will move an element on screen using another component called Animated.

You can see how to setup the dev environment here: https://medium.com/@leonardobrunolima/react-native-tips-setting-up-your-development-environment-for-windows-d326635604ea?source=linkShare-42ccfccbb437-1535561576

Let’s get started creating a new project using react-native cli:

$ react-native init AnimatedBall --version 0.55.4

Now, add a new folder on root path called src and add a new file called Ball.js:

Change the Ball component to show a small black ball on screen:

//import liraries
import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
// create a component
class Ball extends Component {
render() {
return (
<View style={styles.ball} />
);
}
}
// define your styles
const styles = StyleSheet.create({
ball: {
height: 80,
width: 80,
borderColor: 'black',
borderRadius: 40,
borderWidth: 40
},
});
//make this component available to the app
export default Ball;

On App.js import and call the Ball component:

import React, { Component } from 'react';
import {
StyleSheet,
View
} from 'react-native';
import Ball from './src/Ball';export default class App extends Component {
render() {
return (
<View style={styles.container}>
<Ball />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});

It should look like this:

Now let’s get the user gestures using PanResponder component. You can see the full documentation here: https://facebook.github.io/react-native/docs/0.56/panresponder

Import PanResponder component on Ball and create a new instance on constructor:

//import liraries
import React, { Component } from 'react';
import { View, StyleSheet, PanResponder } from 'react-native';
// create a component
class Ball extends Component {
constructor(props) {
super(props);
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (event, gesture) => {
console.log(gesture);
}
});
this.state = { panResponder };
}
render() {
return (
<View
style={styles.ball}
{...this.state.panResponder.panHandlers}
/>
);
}
}
...export default Ball2;

The code above create a new instance of PanResponder and allows any component attached to it to track user gestures. On event onPanResponderMove you can see the result on console when you try to drag the boll on screen:

Now we have the gesture and we can grab the position X and Y from it to animate the ball. Import the Animated component and create a new instance of position. In order to animate a component we have to use the Animated.View, so every component inside it will be animated. In our case we just renamed the View to Animated.View.

//import liraries
import React, { Component } from 'react';
import { View, StyleSheet, PanResponder, Animated } from 'react-native';
// create a component
class Ball extends Component {
constructor(props) {
super(props);
const position = new Animated.ValueXY();
const panResponder = PanResponder.create({
onStartShouldSetPanResponder: () => true,
onPanResponderMove: (event, gesture) => {
position.setValue({ x: gesture.dx, y: gesture.dy });
}
});

this.state = { panResponder, position };
}
render() {
let handles = this.state.panResponder.panHandlers;
return (
<Animated.View
style={[styles.ball, this.state.position.getLayout()]}
{...handles}
/>
);
}
}
...export default Ball;

Now you can drag the ball around the screen. This is a simple example, you can interesting things with PanResponder and Animated components.

That’s all folks,

Thanks for reading!

--

--