When it comes to display based technology, we all love beautiful graphics with animations. In this shot, we are going to get up close and personal with animations in React Native’s mobile application development ecosystem. Assuming that you have already come across the implementations of React Native Reanimated version 1, this shot will show the impact that Reanimated version 2 has had on animation in React Native. The shot will compare and contrast the optimization and easiness of Reanimated 2 vs. Reanimated 1. The basics of Hook based animations are also introduced, which will help you get started with animation in React Native using Reanimated 2.
So, let’s get started!
Now, we are going to get in close and personal with some of the hook based animation system offered by the Reanimated 2 package. But first, we need to get our React Native project ready and install the required dependencies. In order to create a new React Native Project, we are going to use the React Native CLI and execute the following command in the terminal addressed to our desired local repository:
react-native init animations
Now, we can open the project in our favorite code editor (VSCode). Then, in order to run the project in the emulator or the connected device, we need to execute the following command in our project directory terminal:
react-native run-android
Install the package
Now, we are going to install the Reanimated 2 package in React Native.
The steps are a bit complex, but it should get better after the next update as it will allow you to automatically link to native codes.
But, for now, we will follow the complex procedure. First, we need to install the required packages by executing the following commands:
npm install react-native-reanimated@alpha
Along with the reanimated package, we also need the gesture handler. So, we also need to install:
npm install react-native-gesture-handler
After that, we need to configure the babel plugin in the babel.config.js
file. We just need to export the reanimated plugin from the config file (as shown below):
module.exports = {...plugins: [...'react-native-reanimated/plugin',],};
This step is required for the worklet compilations under babel. In the build phase, the plugins inside the Reanimated 2 packages are compiled by babel.
Next, we need to configure some native Android files. For that, go to ./android/app/build.gradle
file and turn on the Hermes engine, as shown below:
project.ext.react = [enableHermes: true // <- here | clean and rebuild if changing]
Then, we need to import and plug in the reanimated plugin into the MainApplication.java
file:
import com.facebook.react.bridge.JSIModulePackage; // <- addimport com.swmansion.reanimated.ReanimatedJSIModulePackage; // <- add...private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {...@Overrideprotected String getJSMainModuleName() {return "index";}**@Override //add this function wholeprotected JSIModulePackage getJSIModulePackage() {return new ReanimatedJSIModulePackage();}**};
Now, re-run the project and see if the app properly builds and runs on an emulator/device:
react-native run-android
For iOS, the setup is automatic. There’s no need to add extra configurations. For detailed information, check the official
. documentation https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#installation
Simple hook based animations
Now, we are going to perform some simple animations using the Reanimated hooks provided by the latest package. The demo code for simple animation is shown below:
import Animated, { useSharedValue, useAnimatedStyle } from 'react-native-reanimated';const App = () => {const offset = useSharedValue(0);const animatedStyles = useAnimatedStyle(() => {return {transform: [{ translateY: offset.value * 255 }],};});return (<><SafeAreaView><View style={{height : 500}}><Animated.View style={[{width: 100, height: 80, backgroundColor: 'blue', margin: 30, borderRadius : 5}, animatedStyles]} /></View><Button onPress={() => (offset.value = (Math.random()))} title="Move" /></SafeAreaView></>);};
Here, we have imported the useSharedValue
and useAnimatedStyle
hooks from the latest reanimated package.
We are familiar with the concept of Animated.value
from the previous version of the reanimated package. However, in Reanimated 2, we will use the useSharedValue
hook instead of Animated.value
.
The functions to keep the animation state
stored are the same. The value stored in this hook is accessible across two threads, UI and JavaScript engine. Shared value carries data, provides reactiveness, and drive animations. By using the value
property, we can read the data from the shared value, which is offset
in the above code.
The useAnimatedStyle
hook captures the shared value and automatically subscribe to updates and the styles.
In the code above, we updated the shared value to some random number while pressing the move button. As a result, the style is updated in the UI thread as shown in the demo below:
Here, the useAnimatedStyle
hook enables the association between Reanimated code and view properties.
Extra hooks available for custom animations
In Reanimated 2, shared value updates can be transformed to animated updates by wrapping the target value with of the animation helpers (such as withTiming
or withSpring
). These are some helper hooks that provide smooth animations based on our needs. Here, we are going to showcase the withSpring
hook in action. The code is provided below:
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';const App = () => {const offset = useSharedValue(0);const animatedStyles = useAnimatedStyle(() => {return {transform: [{ translateY: offset.value * 255 }],};});return (<><SafeAreaView><View style={{height : 500}}><Animated.View style={[{width: 100, height: 80, backgroundColor: 'blue', margin: 30, borderRadius : 5}, animatedStyles]} /></View><Button onPress={() => (offset.value = withSpring(Math.random()))} title="Move" /></SafeAreaView></>);};
The result of spring type animation is shown in the demo:
We can also add a stiffness and damping property to the withSpring
hook. When animated, the effect will cause rectangular boxes to bounce.
Some available custom animations
Here, we are going to get the hint of some custom animations that can be done using the hooks available in the Reanimated 2 package. The code is provided in the code snippet below:
import Animated, { useSharedValue, useAnimatedStyle, withRepeat, withTiming } from 'react-native-reanimated';const App = () => {const offset = useSharedValue(0);const rotation = useSharedValue(0);const animatedStyles = useAnimatedStyle(() => {return {transform: [{ translateX: offset.value * 255 }],};});const customAnimatedStyles = useAnimatedStyle(() => {return {transform: [{ rotateZ: `${rotation.value}deg` }],};});return (<><SafeAreaView><View style={{height : 400}}><Animated.View style={[{width: 100, height: 80, backgroundColor: 'blue', margin: 30, borderRadius : 5}, animatedStyles]} /><Animated.View style={[{width: 100, height: 80, backgroundColor: 'blue', margin: 30, borderRadius : 5}, customAnimatedStyles]} /></View><Button onPress={() => {offset.value = Math.random();rotation.value = withRepeat(withTiming(10), 6, true);}}title="Move"/></SafeAreaView></>);};
Here, we have accompanied two custom animation styles.
The result is shown below:
We can notice the rotation and horizontal sliding animation here.
The Hooks available improve the performance as well as the utility of the overall animation in the React Native ecosystem.
Note: the animations shown in the demo can be a bit slow due to the emulator performance and device specifications. However, there is no doubt that the animations will be smooth on the actual device.
The major objective of this article was to get you familiar with React Native Reanimated 2 package. Assuming that you already have basic interaction with the old Reanimated package, this tutorial article demonstrates the changes Reanimated version 2 has brought in comparison to version 1. The most essential update is the removal of the unintuitive declarative API and the introduction of the