Animating ScrollViews with React Native Reanimated 2

Tanner West
React Native Rocket
4 min readJun 27, 2022
Photo by Akshay Nanavati on Unsplash

Reanimated is a React Native animations library from Software Mansion. Its powerful APIs can be used to animate all kinds of React Native components, and one of my favorites to work with is ScrollView. Check out this “slideshow style” animated ScrollView that scales child components up and down depending on their position on the screen.

Here’s the full code for this component:

Let’s take a look at some of the essential parts of this code to understand what’s going on.

In order to animate our slides, we need to track how far the user has scrolled through our ScrollView . To get this value, we pass an onScroll handler to our Animated.Scrollview .

This brings us to one of the most important hooks in Reanimated, useSharedValue . This hook lets us store a value, much like useState , but our value will be available on both the JavaScript thread along with the rest of our application logic as well as our app’s UI thread.

The fact that our value is available on the UI thread means it doesn’t have to cross the React Native bridge when the user interacts with our app, so the updates to the UI can happen much faster than with React Native alone. This is how Reanimated lets us create 60 fps animations easily.

Here’s how we’ll track that scroll position in a shared value:

Now that we’re tracking the scroll position of our view, we can use it to animate the view’s children, namely the Slide component. We pass the offset value as a prop to the child components, then use the useAnimatedStyle hook to define style rules that will be used to animate the slide:

Using our shared scrollOffset value, we can scale the size of our slide directly on the UI thread. To do this, we’ll use an interpolate function to map that shared value to the desired scale.

Interpolation maps an input value to an output, based on a set of ranges for each. In our case, we want to map the scale of our slides to the scroll position of the view, so that the current slide is scaled to its full size, while the others are scaled down to 80% of their full size.

The first constant we define, input , is what will change as the user scrolls. We get it by dividing the scroll offset by the width of each slide. The result will tell us how many slides the user has scrolled past (i.e. the value of input will be 1 when the user has scrolled to the second slide; this conveniently matches up with the index of the current slide the user is on).

The inputRange constant defines which input values we want to map from. Here we are concerned with the index of our slide and the ones immediately before and after it, since we want to scale the slide up as it approaches the center and down as it scrolls away.

The third argument is the output range, which defines the range of values that our function will output. By passing these three arguments to our interpolation function, we establish these criteria:

  • When the input value is index - 1, the output will be 0.8
  • When the input value is index , the output will be 1
  • When the input value is index + 1 , the output will be 0.8

Our interpolation function will “fill in” the values between those that we defined so that our slide will animate smoothly between them.

By passing Extrapolate.CLAMP as the fourth argument, we are telling the function never to output a value beyond the first and last values of the output range. In other words, any input lower than index — 1 will always output 0.8. Likewise for any value above index + 1 .

That’s it for animating our slides. We can do something similar to animate the position indicator below our slides.

Here, we use a very similar interpolation method to increase the width of our indicator as its corresponding slide approaches the center of the screen. We also use the interpolateColor hook to change the color of the active indicator.

I hope this post has helped you better understand how to animate ScrollView components with Reanimated. Your imagination is the only limit to the beautiful animations you can create once you understand the basics of this powerful library.

As always, please follow me here on Medium and on Twitter @useRNRocket for more React Native and Reanimated content. Questions, corrections, and topic suggestions are always welcome.

--

--