React Native's Animated
Tags: reactnative
Published: 2020-09-22 20:18:35

In working on an app that will incorporate animations, I found a library called Animated for react-native. This library is for building and easily maintaining said animations which focuses on declarative relations between inputs and outputs, configurable transforms in between, and methods for starting and stopping animation execution that is time-based.

The process for creating animations is first setting value, hook it up to style attributes of an animated component, drive updates via animations using timing.

# Features

**Configuring animations**

Animated has three types of animation types. Each animation type provides an animation curve that controls how your values animate from their initial value to the final value:

`Animated.decay()` - starts with an initial velocity and gradually slows to a stop.

`Animated.spring()` - provides a basic spring physics model.

`Animated.timing()` - animates a value over time using easing functions, which by default uses a easeInOut curve that is a gradual acceleration of an object to full speed and finishes by gradually decelerating to a stop.


**How it Works**

Animations are started by calling start() which takes a completion callback that will be called when the animation is done. When the animation finishes running normally, the completion callback will be invoked with {finished: true}. If the animation is done because stop() was called on it before it could finish, then it will receive {finished: false}.
```
Animated.timing({}).start(({ finished }) => {
  /* completion callback */
});
```

**Animatable Components**

Only animatable components can be animated. These are components that bind the animated values to the properties, and do targeted native updates to avoid the cost of the react render and reconciliation process on every frame. 

`createAnimatedComponent()` can be used to make a component animatable.

animatable components:

- Animated.Image
- Animated.ScrollView
- Animated.Text
- Animated.View
- Animated.FlatList
- Animated.SectionList

**Composing animations**

Animations can also be combined in more complex ways using composition functions:

- `Animated.delay()` starts an animation after a given delay.

- `Animated.parallel()` starts a number of animations at the same time.

- `Animated.sequence()` starts the animations in order, waiting for each to complete before starting the next.

- `Animated.stagger()` starts animations in order and in parallel, but with successive delays.

**Combining animated values**

You can combine two animated values via addition, subtraction, multiplication, division, or modulo to make a new animated value:

- `Animated.add()`
- `Animated.subtract()`
- `Animated.divide()`
- `Animated.modulo()`
- `Animated.multiply()`

**Handling Events and Gestures**

Events and gestures, such as panning or scrolling, can map directly to animated values using Animated.event(). This is done with a structured map syntax so that values can be extracted from complex event objects. The first level is an array to allow mapping across multiple args, and that array contains nested objects.

Example with horizontal scrolling gestures to map event to scrollx:

For example, when working with horizontal scrolling gestures, you would do the following in order to map event.nativeEvent.contentOffset.x to scrollX (an Animated.Value):
```
 onScroll={Animated.event(
   // scrollX = e.nativeEvent.contentOffset.x
   [{ nativeEvent: {
        contentOffset: {
          x: scrollX
        }
      }
    }]
 )}
```

There are other features and functions like interpolation functions which you can read about more in depth on https://reactnative.dev/.

**References**
- https://reactnative.dev/docs/animated
- https://reactnative.dev/docs/animations.html