This is a tutorial on how to make a ripple effect for Material Design’s Icon Button. We’ll use Animated API, which is a part of React Native.
You can find an IconToggle component in open-source project called react-native-material-ui. If you want to rather see it in a real app you can check out the Savee.io!
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 the 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 the red star icon in the last example above.
Let’s code ✍️
First of all, we’ll create a 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.
Again, we took Icon component from react-native-material-ui. Now, the animation.
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 the user presses icon. It starts from 0.01 (not zero) because there is an issue in React Native. Later, when the 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 color for icon and ripple effect. Look at line 12 and 18. We would like to use a native thread for Android platform (edit 2018: now you can also use the native thread for iOS as well) because then the animation doesn’t block the JS thread. In a 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.
You can find the whole code on my Github account. Note that it’s not ready for production. For this purpose, you can use react-native-material-ui that I’m developing as an open source library and using it to build the financial app called Savee.io.
Did you like it? Clap and Follow me! 👏
Actually you don’t have to do anything of that. But it will help me a lot. It’s a big motivation to the next work. Next articles like this for you guys.
About me 👦
I am an author of Savee.io (which I also use as a playground for my animations 🤷). I open-sourced react-native-material-ui and react-native-motion libraries. Writing about them in this blog.
If you need a help with your React Native app (animations, performance, etc.), let me know, please ;) I will be happy to discuss it.