How to add animations to your NativeBase App
Tags: react, reactnative, webdev, appdevelopement
Published: 2022-02-10 11:02:17

**Introduction**

**What is the difference between a “Good” app and a “Great” app?**

When I think about this question, a few things come to mind. But the one thing that most users will notice and remember is Interaction Animations. 

So, in this tutorial, we will share with you, how to add animations to your NativeBase app, using `Reanimated`. 

**What are We Creating**

We will create a Todo app and add interaction animations to it, to enhance the user experience.

To make our Todo app lively and enjoyable, we will use the three animations highlighted below.

1. Add a small rotate the button on click.
2. Change the background color of the completed item when clicked.
3. Animating removing items from the list by swiping the item left.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ld96r4alotxkyxulndq.gif)

**Implementing Individual Animations**

- Rotation 🔁

```javascript
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
  useDerivedValue,
  interpolate,
  withRepeat,
} from "react-native-reanimated";
const animation = useSharedValue(0);
const rotation = useDerivedValue(() => {
  return interpolate(animation.value, [0, 360], [0, 360]);
});
const buttonRotation = useAnimatedStyle(() => {
  return {
    transform: [
      {
        rotate: rotation.value + "deg",
      },
    ],
  };
});
const startAnimation = () => {
  animation.value = withRepeat(
    withTiming(30, {
      duration: 400,
    }),
    2,
    true
  );
};
const buttonRotation = useAnimatedStyle(() => {
  return {
    transform: [
      {
        rotate: rotation.value + "deg",
      },
    ],
  };
});

// JSX for button
<TouchableWithoutFeedback
  onPress={() => {
    if (inputValue) addItem(inputValue);
    setInputValue("");
  }}
  onPressIn={startAnimation}
>
  <Animated.View
    style={[
      {
        height: 50,
        width: 100,
        backgroundColor: colors["primary"][700],
        borderRadius: 3,
        alignItems: "center",
        justifyContent: "center",
        paddingHorizontal: 12,
      },
      buttonRotation,
    ]}
  >
    <Text
      color="white"
      textAlign="center"
      fontSize="md"
      justifyContent="center"
    >
      Add Task
    </Text>
  </Animated.View>
</TouchableWithoutFeedback>
```
Rotation can act as the base for tons of cool interactions. We used `useSharedValue` hook from the `reanimated` library to share the value between the react-native UI thread and animation thread.

To get the transformed shared value if one of the underlying shared value change, we have used the `useDerivedValue` hook. We then used the `useAniamtedStyle` hook to make the association between the shared values and the view properties of add button.

By clicking on the button, the start animation function is called. This changes the shared value and all the subsequent changes occur based on the shared value used in animations. The video below demonstrates, what it looks like 🙂.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xdsslt1eastg6not80u4.gif)

- Changing of background color on click  🎨

We inserted this animation to show that a certain task is pending. We are changing the background color as shown below to denote the completion of the task. Here we are changing the `backgroundColor` property of the view with some delay animation.

```javascript
const { colors } = useTheme();
const progress = useDerivedValue(() => {
  return props.item.isCompleted
    ? withTiming(1, { duration: 2000 })
    : withTiming(0, { duration: 2000 });
});
const rContainreStyle = useAnimatedStyle(() => {
  const backgroundColor = interpolateColor(
    progress.value,
    [0, 1],
    ["white", colors["muted"][100]]
  );
  return {
   ..
   backgroundColor,
   ..
  };
});


//JSX
<Pressable
  onPress={() => {
    props.handleStatusChange(props.itemI);
  }}
>
  <PanGestureHandler onGestureEvent={gestureMethod}>
    <Animated.View style={[styles.containreStyle, rContainreStyle]}>
      <Text fontSize="lg" px={6} color="coolGray.800">
        {props.item.title}
      </Text>
    </Animated.View>
  </PanGestureHandler>
</Pressable>
```
`useTheme` hook offered by NativeBase and allows you to tap into the theming system provided by NativeBase. The video below demonstrates this animation.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5truy4i4ukcu8sd5jwec.gif)

- Removing the card 🗑️

We used this animation to show that once we complete a task we just simply slide the card left 👈. With one swipe the card is removed. 

Using `PanGestureHandler` from react-native-gesture-handler to capture  touch event and based on the swipe value assigned we animated the translateX, `marginVertical`, opacity, and height properties of view.

```javascript
import { PanGestureHandler } from "react-native-gesture-handler";
const SCREENWIDTH = Dimensions.get("window").width;
const TRANSLATEXTHRESHOLD = -SCREENWIDTH * 0.34;
const translateX = useSharedValue(0);
const MARGIN = useSharedValue(10);
const CONTAINERHEIGHT = useSharedValue(70);
const OPACITY = useSharedValue(1);
const gestureMethod = useAnimatedGestureHandler({
  onStart: (event, ctx) => {},
  onActive: (event, ctx) => {
    translateX.value = event.translationX;
  },
  onEnd: (event, ctx) => {
    const isDismissed = translateX.value < TRANSLATEXTHRESHOLD;
    if (isDismissed) {
      translateX.value = withTiming(-SCREENWIDTH);
      CONTAINERHEIGHT.value = withTiming(0);
      MARGIN.value = withTiming(0);
      OPACITY.value = withTiming(0);
    } else {
      translateX.value = withTiming(0);
    }
  },
});
const rContainreStyle = useAnimatedStyle(() => {
  const backgroundColor = interpolateColor(
    progress.value,
    [0, 1],
    ["white", colors["muted"][100]]
  );
  return {
    transform: [{ translateX: translateX.value }],
    height: CONTAINERHEIGHT.value,
    opacity: OPACITY.value,
    marginVertical: MARGIN.value,
    backgroundColor,
  };
});

//JSX
<Pressable
  onPress={() => {
    props.handleStatusChange(props.itemI);
  }}
>
  <PanGestureHandler onGestureEvent={gestureMethod}>
    <Animated.View style={[styles.containreStyle, rContainreStyle]}>
      <Text fontSize="lg" px={6} color="coolGray.800">
        {props.item.title}
      </Text>
    </Animated.View>
  </PanGestureHandler>
</Pressable>
```
The video below demonstrates the animation: 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xsjwq00xkgiibcsyahwb.gif)

**Conclusion**

Animation plays a very pivotal role in enhancing the overall user experience of any application. The experience of a simple application can be improved ten folds by the use of simple animations. 

For achieving that outcome React animated plays an important role. NativeBase being an awesome Library offered such a variety to use components and Pseudo props that helped in reducing the code complexity and improving the code quality. 

With the use of NativeBase what we can achieve is something great. The experience of using apps essentials in everyday life, like the ToDo application, can be enhanced incredibly using animations from NativeBase.