Basically, we link animations based on the value of the scroll x. Say the device width is 100, when user swipes to the left and gets to the next screen, we can express those as 100 x 2, 100 x 3, and so on …

So if we start the animation at 0 and end it at 200, we can write the input range and output range like this,

If the screen width was 100, it’d be [0, 100, 200] for index = 1 , and [100, 200, 300] for index = 2 . When the scroll position is at 150 , first screen is half way done exiting, and the second screen is half way done entering.

Adding animations

Since they are all set up, it is time to write the animations. We need index value as a prop, so we can write a function that returns an array of transform animations like this,

Notice the Animated.Value of x offset, which is to track the input and output values for the animations. We don’t need three of them because the inputRange (device width) is the same for all three animations.

scale is for the size of the Screen component and rotateX and rotateY are for rotation. As you can see, transform accepts an array of objects, and the rotate transformations require a string expressed in degrees.

I won’t talk about Animated library in depth here but if you’d like to know more about that, please read my previous blog post or refer to FB’s official page.

Linking Animations to ScrollView

This is the last step! We are going to use ScrollView to integrate touch locking “responder” system. They are a few props that we need to pass in to make this work.

Let’s start with scrollEventThrottle . That prop is responsible for controlling “frequency” of the event.

horizontal enables horizontal scrolling. pagingEnabled moves scrollView to nearest multiple of it’s own width (like snapping to the grid).

onScroll is where we can pass the animation. We pass xOffset we declared earlier and set useNativeDriver to true . This is necessary because this allows native code to perform the animation on the UI thread without having to convert the Javascript on every frame. If this was set to false , the Screen animations would be lagging.

That’s about it! If you wrote everything correctly, you will see this,

funnnnn

Conclusion

This would be a nice UI animation if you were planning to use it for a simple navigation. However, if you want this for a very long list of items, there are few things I’d like to note.

The ScrollView component renders all its child components. Therefore, if you were to work with a long list, there might be a performance downside.

If that’s the case, consider using FlatList instead, which renders items lazily to save memory and processing time. You would have to write a different inputRange since FlatList removes items that scroll way off screen.

I think this is pretty neat UI animation that’s pretty simple to use. As always, I hope this tutorial was helpful to your project. Until my next blog,

Happy coding!

Resources

This tutorial was requested by Akshay Kadam. The original design was by Zachary Gibson. Thanks for the request, it was really fun deciphering how it was written :)