Ripple effect in React Native

Here’s a tutorial how to make ripple effect for Material Design’s Icon Button. We’ll use Animated API, which is a part of React Native.

An IconToggle component is included in open source react-native-material-ui library. I’m using this library for booking system by Reservio.

The idea …

We’ll make three Views. One of them as a container for IconToggle component. Another one as a container for ripple effect and last one as a container for Icon. We’ll wrap them in React Native’s TouchableWithoutFeedback component that fires onPressIn and onPressOut events.

Why do we need both of these events? Because there are two different animations. A scale animation and an opacity animation. They may run together, of course. So, is the onPressIn event enough? No. Because there could be a situation when user presses the button for a longer time. Then we need scale animation to run first and wait for onPressOut event that runs opacity animation. It’s exactly how the icon button’s ripple effect works. I simulated that with red star icon in the last example above.

Let’s code …

First of all, we’ll create blank page for this example. Then we’ll create IconToggle component and the ripple effect animation. Finally, we’ll make some correlation.

Now, we have a view with Toolbar which is known from Material Design by Google. The Toolbar is not a goal of this tutorial, so we took it from react-native-material-ui library. Then, we put the IconToggle components and implement it in the following Gist.

Let’s animate …

On lines 14 and 15 we created two Animated.Values. One of them for scale animation and second for opacity animation. We pass them to Animated.View via its props. The scale animation begins inside of onPressedIn function, that is fired after user presses icon. It starts from 0.01 (not zero) because there is an issue in React Native. Later, when user releases the button, the opacity animation will start. It doesn’t matter if the scale animation is still running or not. After the opacity animation is done, we need Animated.Values to be set to init values (line 34). That’s it. That’s the whole ripple effect.

In this code, we just added a colour for icon and ripple effect. Look at line 12 and 18. We would like to use native thread for Android platform because then the animation doesn’t block the JS thread. In real application we’ll probably fire onPress callback and there will be another code to run. We don’t want to block it, so it’s better to use native thread for animation.