How to Craft Animations in React with React Simple Animate

William Le

In this article, learn how to craft animations in React using a new library called React Simple Animate.

Animations in React are difficult. Depending on whether you use inline-styles, or a library like styled-components it usually entails a lot of work from your end to write something that’s easy-to-understand, and therefore maintainable.

react-simple-animate provides you with a set of utility React components to craft animations –– and you don’t have to buy-in to any other styling library! You already know everything to ship really great animations in React!

<Animate/>

The most simple component exported by react-simple-animate is <Animate/>. The basic props to provide are play, startStyle, and endStyle.

import React from 'react';
import { Animate } from 'react-simple-animate';

class MovingCircle extends Component {
 
  state = {
    play: false
  }
  
  render() {
    return (
      <Animate
        play={this.state.play}
        startStyle={{ transform: 'translateX(0px)' }}
        endStyle={{ transform: 'translate(300px)' }}
      >
        <Circle/>
      </Animate>
    )
  }
}

When play is “true” it will trigger the animation. Under the hood it simply animates between startStyle and endStyle. If you’ve ever used CSS transition properties, it’s conceptually very similar.

Notice that it doesn’t use a CSS-in-JS library (eg., styled-components), and just uses inline-styles. The benefit of this approach is that there isn’t additional tooling required to build CSS assets. React already knows how to work with inline-styles! 😛

<AnimateKeyframes/>

One pain point of using inline-styles is that it lacks some features from CSS… among those features are @keyframe animations. With <AnimateKeyframes/> you have an drop-in equivalent:

import React from 'react';
import { AnimateKeyframes } from 'react-simple-animate';

class SpinningSquare extends Component {
  render() {
    return (
      <AnimateKeyframes
        play={true}
        iterationCount="infinite"
        direction="normal"
        durationSeconds={4}
        keyframes={[
          'transform: rotateZ(0)',
          'transform: rotateZ(360deg)'
        ]}
      >
        <Square/>
      </AnimateKeyframes>
    )
  }
}

The API for <AnimateKeyframes> is mostly self-explanatory. It takes an array with the animation states, and assumes those are evenly distanced states. You can override this behavior by specifying the timing:

import React from 'react';
import { AnimateKeyframes } from 'react-simple-animate';

class SpinningSquare extends Component {
  render() {
    return (
      <AnimateKeyframes
        play={true}
        iterationCount="infinite"
        direction="normal"
        durationSeconds={4}
        keyframes={[
          { 0: 'transform: rotateZ(0)' }, // 0%
          { 50: 'transform: rotateZ(180deg)' }, // 50%
          { 100: 'transform: rotateZ(360deg)' } // 100%
        ]}
      >
        <Square/>
      </AnimateKeyframes>
    )
  }
}

Keyframe animations are great when you need to perform pre-scheduled animations. With <AnimateKeyframes/> you have a clean API to conduct these animations that’s really concise and readable.

If you set play to "false" it will pause the animation for you. You can resume the animation by switching back to "true"

<AnimateGroup/>

Sometimes you need to sequence animations together. This is where react-simple-animate really shines! Using <AnimateGroup/> you wrap your <Animate/> elements and provide a sequenceIndex to define the sequence order.

import React from 'react';
import { Animate, AnimateGroup } from 'react-simple-animate';

class DramaticLetters extends Component {

  state = {
    play: false
  }

  render() {
    return (
      <AnimateGroup play={this.state.play}>
          {'ALLIGATOR'
            .split('')
            .map((letter, index) => (
              <Animate
                key={index}
                sequenceIndex={index}
                durationSeconds={0.1}
                startStyle={{
                  display: 'inline-block',
                  opacity: 1,
                  transform: 'translateX(0px)'
                }}
                endStyle={{
                  display: 'inline-block',
                  opacity: 0,
                  transform: 'translateX(-10px)'
                }}
              >
                <BlockLetter>{letter}</BlockLetter>
              </Animate>
            ))}
        </AnimateGroup>
    )
  }
}

The API is powerfully expressive! It’s just a few lines and boom… sequenced animations! You can really do some interesting things with this. Like stuff you see in those .mp4 videos of user interfaces doing really outlandish animations. Now you can do ‘em too!

import React from 'react';
import { Animate, AnimateGroup } from 'react-simple-animate';

class DramaticList extends Component {

  state = {
    play: false
  }

  render() {
    return (
      <AnimateGroup play={this.state.play}>
        {
          travelDestinations
            .map((item, index) => (
              <Animate
                key={item.name}
                sequenceIndex={index}
                durationSeconds={0.25}
                startStyle={{
                  opacity: 1,
                  transform: 'translate3d(0, 0, 0px)',
                  willChange: 'transform, opacity',
                }}
                endStyle={{
                  opacity: 0,
                  transform: 'translate3d(15px, 35px, 0)',
                  willChange: 'transform, opacity',
                }}
              >
                <ListItem
                  name={item.name}
                  description={item.description}
                  coverImage={item.coverImage}
                />
              </Animate>
            ))
        }
      </AnimateGroup>
    )
  }
}

All images are kindly provided by the Unsplash (unsplash.com) community of photographers

Conclusion

Give this library a try if you’re looking for a clean alternative for crafting animations in React. The only two dependencies are react and react-dom, so this library should get you a lot of mileage, and be well-supported in the future.

📓 Check out the official documentation for more usage details, and demos!

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#