Interpolate Colors like a pro with React Native Reanimated 2 šŸš€

Enzo Manuel Mangano
6 min readMay 19, 2021

Whatā€™s up mobile devs? Today we are going to understand the concept behind the interpolateColor function from the react-native-reanimated (v2) package.
To enhance the learning experience, we will make this beautiful animation from scratch. The goal will be to apply color interpolation when the switch from Light Theme to Dark Theme or vice versa occurs.

If youā€™re more of a video tutorial person, the same content in this medium article is available as a video on my YouTube channel.

P.S: Iā€™m creating an entire series on the Reanimated 2 basics.
Before going on, know that all the code is entirely available on GitHub (in the 03-interpolate-color folder):

Letā€™s prepare our environment šŸ¢

The first step is to create a React Native project with expo-cli (since itā€™s the fastest way to do it).

expo init interpolate-color

The second step is to install react-native-reanimated (make sure in the package.json that you have at least version 2)

yarn add react-native-reanimated

To enable Reanimated worklets you need to add the reanimated plugin in the babel.config.js file.

I also share below the App.tsx file since I have defined some colors that we will use later. Of course feel free to use the colors you prefer.

A missing piece in our setup: The Switch! šŸŽ›

The first component to be included in the UI is the Switch. Weā€™re going to use the Switch from react-native and use it as a kind of animation controller.
When the Switch is toggled the theme becomes Dark, otherwise it remains Light.

Below for simplicity I have uploaded the resulting code.

Letā€™s get our hands dirty! šŸ¤“

In order to animate things, we need to convert the View in an Animated.View, using Animated from react-native-reanimated.
Moreover since the backgroundColor will be handled on the UI Thread by reanimated, we need to use the useAnimatedStyle hook.

Wait what? šŸ¤Ø
UI Thread, useAnimatedStyle, Animated.View what are those stuffs?
If this is your first time hearing about these topics, I definitely recommend you to check out my first video on Reanimated 2:

Letā€™s Interpolate Colors šŸŽØ

Alright. We need to use interpolateColor, but how do we use interpolateColor? šŸ§
We need at least three ingredients: a value, an input range and an output range.

The idea behind interpolateColor is then to interpolate a value of type number and map it to an output range.

In the code below we can see that the value on the basis of which we perform the interpolation is progress (and it is a SharedValue).
Of course, we could have used the useSharedValue hook to define progress, but the point is that progress must be ā€œderivedā€ continuously from the current theme value.

At this point it is very easy to understand how interpolateColor works.
Letā€™s try to understand how the backgroundColor will behave.

  1. When progress is equal to 0 then backgroundColor will be equal to Colors.light.background;
  2. When progress is equal to 1 then backgroundColor will be equal to Colors.dark.background;
  3. When progress is between 0 and 1 then backgroundColor will be a color between Colors.light.background and Colors.dark.background;

Hereā€™s the result.

Wait. Why doesnā€™t it work as smooth as expected? šŸ§

The point is that as defined, progress changes noticeably between 0 and 1 (or vice versa).
However, it never takes on any value between 0 and 1.
To solve this problem we can simply wrap everything with the withTiming function from react-native-reanimated.

Hereā€™s the magic šŸš€

Just to make sure I havenā€™t lost you in the explanation, I attach the actual code below. šŸ“–

Whatā€™s missing?

Letā€™s focus on the Circle āšŖļø

As before, we also need to define the circle as Animated.View, as we will animate its backgroundColor.

I attach below the style I used to define circle. As you can see, it is more difficult to define the styling than the animation itself šŸ˜¬

Finally, in order to interpolate the backgroundColor of our circle, we just need to replicate the same logic as before.
In fact, the only thing that changes from the rStyle used previously, is that in this case, in the output range we need to specify the colors we expect from the circle (Colors.light.circle instead of Colors.light.background for instance).

Just to be sure, I attach the complete code of the App.tsx file with the addition of the circle animation šŸ¢

Letā€™s focus on the Text šŸ“–

Having reached this point, we are now experts on the subject.
As before, to animate our Text, we need to define it as Animated.Text andā€¦

ā€¦ append to it the reanimated style rTextStyle:

In the rTextStyle we just need to pay a little attention to the fact that we are no longer animating the backgroundColor, but rather the text color

Congratulation, you did it! šŸ„³

And hereā€™s the final result šŸ„šŸ„šŸ„

Iā€™m extremely sure you donā€™t need it by now, but just to be totally sure you didnā€™t miss anything, I attach the final version of the code below. šŸ˜Œ

Conclusions šŸ¤“

If youā€™ve made it this far youā€™re probably really into reanimated 2 (or even more likely you were too lazy to read the article).
Anyways I want to share with you my GitHub Repo ā€œAnimate with Reanimatedā€ where I try to build from scratch simple and instructive animations with the help of react-native-reanimated and react-native-gesture-handler.

--

--

Enzo Manuel Mangano

I am 24 years old. My biggest passions are music, chess, photography, and of course programming.