How I built a Tinder inspired loader in React Native

Yousef Kama
4 min readAug 24, 2016

--

In this post I’m going to describe the challenges I faced while building a Tinder inspired Loader. I divided it into three challenges.

Challenge 1: Layout

MILA KUNIS!

In the screenshot above you can see that the avatar and the circle behind it, are both centered.

Thanks to Flexbox, it’s finally easy to center an element horizontally and vertically, by just adding “justifyContent: ‘center’” and “alignItems: ‘center’”. In this situation, however, I had to center two elements. I could use Flexbox for either the avatar or the circle. I chose the avatar. For the background circle I used “position: absolute” and negative margins to accomplish my goal.

container: {
flex: 1,
justifyContent: 'center', // this centers the avatar vertically
alignItems: 'center', // this centers the avatar horizontally
},
circle: {
width: circleSize,
height: circleSize,
position: 'absolute',
left: deviceWidth/2,
top: deviceHeight/2,
marginLeft: -circleSize/2,
marginTop: -circleSize/2
},

Challenge 2: Animation

React Native has a library for animations, called Animated. I used it to scale the circle and fade it out. Animating the circle wasn’t the problem, if you know how to use the interpolate methods, but repeating the animation in a loop was.

I knew, that the “react-native-animatable” library provides a property called “iterationCount: infinitive”, but the Animated API does not have such feature built in. So I had to build it on my own.

My first idea was to do it recursively. I created a new function, which sets the animation value to zero, then I animated it to the value 1 and in the callback, when the animation finished, I called the function again.

animate() {
this.anim.setValue(0);
Animated.timing(this.anim, {
toValue: 1,
duration: 3000,
easing: Easing.in
})
.start(this.animate.bind(this));
}

Although it worked and the code looked clean IMO, it had one problem: I couldn’t stop the animation, it would repeat forever.

I ended up using setInverval and clearInterval to create a loop and to be able to stop it whenever I want to.

Challenge 3: Interaction

tap tap tap

The final challenge was the interaction with the avatar. Every time you tap on it, a new circle would appear, without interfering with the previous one. This means, there could be multiple circles on the screen at the same time. I realized quickly, that this isn’t going to work with the current code.

So I created a second component, which represents a single circle. Each circle has its own “animation lifecycle”. I still used setInterval, but now it creates a new circle instead of managing the animation. When you press on the avatar, another circle gets created.

setCircleInterval() {
this.interval = setInterval(this.addCircle, 3000);
this.addCircle();
}
addCircle() {
this.setState({
circles: [...this.state.circles, this.counter]
});

this.counter++;
}

One thing was still missing. As long as the user presses and holds the avatar, new circles must not be created, only after he released the screen. Fortunately, the Touchable components have two events which helped exactly with that: onPressIn and onPressOut. When the first event is called, the interval gets cleared, so there won’t be created any new circles and when the second event is fired, the interval (in which the circles are created) is set again.

onAvatarPressIn() {
clearInterval(this.interval);
}
onAvatarPressOut() {
this.setCircleInterval();
}

Conclusion

This exercise took me a couple of hours and I’m quite happy with the outcome. Creating UIs in React Native is a lot of fun and I’m looking forward to building other components from popular apps in React Native. If you have any ideas or wishes, please let me know!

Feel free to check out the full code on Github.

Thanks for reading! ❤️

If u wanna see more articles like this, don’t forget to follow me on Medium!

--

--