Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

react native
community creator

How to create animations using react native reanimated

krissanawat

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!

Using Hook based animations using Reanimated 2

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.gradlefile 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; // <- add
import com.swmansion.reanimated.ReanimatedJSIModulePackage; // <- add
  ...
  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
  ...

      @Override
      protected String getJSMainModuleName() {
        return "index";
      }

      **@Override //add this function whole
      protected 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.

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.

Recap

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 Pure JavaScript animation workletsextracts the react-native code and executes it in a separate JS context on the main thread. The overall animation spectrum is optimized as there is no longer a bridge between the JavaScript thread and UI thread. The updates are made directly to the UI thread; thus, making the animations smoother and more optimized. Another important thing that we demonstrated here is the use of hook based animations. The basics provided in the tutorial will help you create a more advanced form of animation using hooks.

RELATED TAGS

react native
community creator
RELATED COURSES

View all Courses

Keep Exploring