React Native Animations

React.Animated

I recently had to create some animations in React Native. Their animation library is relatively new and not fully documented yet. I had a hard time learning the API, so I am going to document what I've learned so you can have another resource in your learning process.

React.Animated is one of React Native's two animation systems. The other is React.LayoutAnimation. I will only be covering the former in this post.

How I Understand it

React.Animated works similar to how CSS transition animations works. It is an API to specify how the screen animates changes to component's transform.

A transform is an altered rendering of the component. For example, a translate(100px, 0px) transform takes the rendered component and moves it 100px along the x-axis and 0px along the y-axis.

Whenever, the translate transform changes it's x and y value, the component's presentation is updated. It usually happens "instantly". CSS Transitions and React Native's Animated library are APIs to manipulate their respective component's presentation update.

CSS Analogy

1. Define Initial Animatable Style Property

// CSS
.slide-in-box {
  transform: translate(0px, 0px);
  transition-property: transform;
}

2. Set Animatable Style Property on Component

// HTML
<html>  
  <body>
    <div class='slide-in-box'>My Sliding Box</div>
  </body>
</html>  

3. Tweak Style Property Transition Animation

// CSS
.slide-in-box {
  ...

  transition-duration: 2s;
  transition-timing-function: ease-in;
  transition-delay: 1s;
}

4. Change Animatable Style Property's Value

// ES6 JS
window.onload(() => {  
  const box = document
    .getElementsByClassName('slide-in-box')
    .item(0);

  box.style.transform = 'translate(200px, 0px)';
});

5. Profit

React Native

1. Define Initial Animatable Style Property

React.Animated has classes that encapsulates animated values. Instances of these classes have helper methods that will generate transform styles. You'll need to dig through the source to see what methods are available.

You can find a list of available transforms here.

// ES6 JSX
const React = require('react-native');  
const {  
  Animated,
  Easing,
  Text,
  Component
} = React;

class SlidingBox extends Component {  
  constructor(props) {
    super(props);

    this.state = {
      slidingAnimationValue: new Animated.ValueXY({ x: 0, y: 0 });
    }
  }
}

2. Set Animatable Style Property on Component

In React Native, you need to use an React.Animated.*view component. There is no explicit list of animatable components, but the source code, examples, and other blogs suggests that there is only 3 at the moment.

Animated.View  
Animated.Image  
Animated.Text  
// ES6 JS
class SlidingBox extends Component {  
  ...

  render() {
    const slidingAnimationStyle = this.state
      .slidingAnimationValue
      .getTranslateTransform(); // Get the initial transform style

    return (
      <Animated.View style={slidingAnimationStyle}>
        <Text>My Sliding Box</Text>
      </Animated.View>
    );
  }
}

3. Tweak Style Property Transition Animation

// ES6 JS
class SlidingBox extends Component {  
  ...

  componentDidMount() {
    const animationConfig = {
      duration: 2000, // milliseconds
      delay: 1000, // milliseconds
      easing: Easing.in(Easing.ease),
    };
  }
}

4. Change Animatable Style Property's Value

// ES6 JS
class SlidingBox extends Component {  
  ...

  componentDidMount() {
    const animationConfig = {
      duration: 2000, // milliseconds
      delay: 1000, // milliseconds
      easing: Easing.in(Easing.ease),
    }

    const value = this.state.slidingAnimationValue;
    const slidingInAnimation = Animated.timing(value, {
      ...animationConfig, // ES6 spread operator
      toValue: {
        x: 200,
        y: 0,
      },
    }).start();
  }
}

Profit

If you were observant, you'll notice that the result of Animated.timing(...) is an object that has a start() method. That method is what initiates the animations. Thus, you can trigger animations on React Native's Animated.*view components anywhere you can stick a function. Prime examples are component lifecycle hooks and user interaction handlers.

Furthermore, React Native's Animated library has support for running animations in sequence, parallel, and much more. Check out their docs.

Further Reading

I've only scratched the surface of React Native animations. The animations documentation is dense, but it is still new. As such, it may not be as thorough or newbie friendly as you might expect. Your best bet is to check out the documentation, look for guides from the community, and dig through the source code.

With that in mind, here are the three links that helped me complete this post:

  1. React Native Animations documentation.
  2. browniefed's awesome animations tutorial.
  3. React Native's Animated source directory