TECHY360
Everything You Need To Know About Tech

5 ways to create animation in React 2019

0 68

Creating animation in the React application is a popular topic. Many developers only animate using CSS, adding classes to HTML tags. This is a great way, but if you want to create complex animations, pay attention to other approaches.

Let’s talk about them.

1. CSS method

This is one of the best techniques for simple animation. If you use it instead of importing JavaScript libraries, the assembly remains small and the browser spends less resources. This greatly affects application performance. If you have a simple animation and are worried about the size of your build, pay attention to this method.

Let’s look at an example of a hamburger menu:

Hamburger Menu
Hamburger Menu

This is a simple menu with the CSS property and trigger className = "is-nav-open"for the HTML tag. Ways to implement a lot. One of them is to create wrapperabove navigation and cause changes in the fields. Navigation has a constant width, equal 250px, and wrapperwith a property margin-leftor translateXwith the same width. If you want to show navigation, you must add className = "is-nav-open"for wrapperand move wrappertomargin-left / translateX: 0;

export default class ExampleCss extends Component {
    handleClick() {
        const wrapper = document.getElementById('wrapper');
        wrapper.classList.toggle('is-nav-open')
    }
    render() {
        return (
            <div id="wrapper" className="wrapper">
                <div className="nav">
                    <icon
                        className="nav__icon"
                        type="menu-fold"
                        onClick={() => this.handleClick()}/>
                    <div className="nav__body">
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit.
                        Beatae ducimus est laudantium libero nam optio repellat
                        sit unde voluptatum?
                    </div>
                </div>
            </div>
        );
    }
}

And CSS styles:

.wrapper {
    display: flex;
    width: 100%;
    height: 100%;
    transition: margin .5s;
    margin: 0 0 0 -250px;
}

.wrapper.is-nav-open {
    margin-left: 0;
}

.nav {
    position: relative;
    width: 250px;
    height: 20px;
    padding: 20px;
    border-right: 1px solid #ccc;
}
.nav__icon {
    position: absolute;
    top: 0;
    right: -60px;
    padding: 20px;
    font-size: 20px;
    cursor: pointer;
    transition: color .3s;
}

.nav__icon:hover {
    color: #5eb2ff;
}

This method is necessary in most cases. It’s better to write a few lines of CSS and modify className then to import and use large libraries. And users will be grateful that the application works quickly in the browser.

2. ReactTransitionGroup

This add-on was developed by guys from the ReactJs community. ReactTransitionGroup easily implements basic CSS animations and transitions.

Developers describe this library like this:

A set of components for managing states over time, specifically designed for animations.

Three things you need to know about this component:

  1. ReactTransitionGroup changes classes when a component’s life cycle changes. The animated style, in turn, should be described in CSS classes.
  2. ReactTransitionGrouphas a small size. It must be installed in the React application package and will not significantly increase your build. You can also use CDN.
  3. ReactTransitionGrouphas 3 components ( TransitionCSSTransitionand TransitionGroup). To start the animation, you need to wrap the component in them.

Let’s see how to make a similar animation.

First, you need to import CSSTransitionGroupfrom react-transition-group. Then you must wrap the list and set the property transitionName. Each time a child is added or removed in CSSTransitionGroup, it gets animation styles.

<CSSTransitionGroup
    transitionName="example">
    {items}
</CSSTransitionGroup>

If you set a property transitionName = "example", the classes in the style sheets must begin with the name of the example.

.example-eneter {
    opacity: 0.01;
}

.example-enter.example-enter-active {
    opacity: 1;
    transition: opacity 300ms ease-in;
}

.example-leave {
    opacity: 1;
}

.example-leave.example-leave-active {
    opacity: 0.01;
    transition: opacity 300ms ease-in;
}

You can see the basic usage ReactTransitionGroup.

Of course, you need to add a bit of logic. Two methods should be described to implement our sample contact list:

handleAdd– adds new contacts, gets a random name and puts it into an array state.items. (a package is used for a random name random-name).

handleRemove– delete contact by index in the array state.items.

import React, { Component, Fragment } from 'react';
import { CSSTransitionGroup } from 'react-transition-group'
import random from 'random-name'
import Button from './button'
import Item from './item'
import './style.css';

export default class ReactTransitionGroup extends Component {
    
    constructor(props) {
        super(props);
        this.state = { items: ['Natividad Steen']};
        this.handleAdd = this.handleAdd.bind(this);
    }

    handleAdd() {
        let newItems = this.state.items;
        newItems.push(random());
        this.setState({ items: newItems });
    }

    render () {
        const items = this.state.items.map((item, i) => (
            <Item
            item={item}
            key={i}
            keyDelete={i}
            handleRemove={(i) => this.handleRemove(i)}
            />
        ));

    return (
        <Fragment>
            <Button onClick={this.handleAdd}/>
                <div className="project">
                    <CSSTransitionGroup
                    transitionName="example"
                    transitionEnterTimeout={500}
                    transitionLeaveTimeout={300}
                    >
                        {items}
                    </CSSTransitionGroup>
                </div>
        </Fragment>
    );
}
};

3️. React-animations

React-animations is a library built on animations from animate.css . It is easy to use and has many animation collections. React-animation works with any inline-style library that supports using objects to define key animation frames, such as Radium, Aphrodite, or styled-components.

You can look at the animation in the gif:

React Animations

Let’s see how it works. For example, bouncing animation.

React Bouncing Animation
React Bouncing Animation

First you need to import the selected animation from react-animations.

const Bounce = styled.div`animation: 2s ${keyframes`${bounce}`} infinite`;

When the component is created, you need to wrap any HTML code or component for the animation.

<bounce><h1>Hello Animation Bounce</h1></bounce>

Example:

import React, { Component } from 'react';
import styled, { keyframes } from 'styled-components';
import { bounce } from 'react-animations';
import './style.css';

const Bounce = styled.div`animation: 2s ${keyframes`${bounce}`} infinite`;

export default class ReactAnimations extends Component {
    render() {
        return (
            <Bounce><h1>Hello Animation Bounce</h1></bounce>
        );
    }
}

Animation works. It is basic and very simple.

There is a good solution for using this animation when scrolling – react-animate-on-scroll.

4️. React-reveal

React Reveal is an animated framework for React. It has basic animations, such as fading out, reflection, scaling, rotation, and other more complex animations. It allows you to manage all the animations using props, for example, to set additional settings: position, delay, distance, cascade, and many others. You can see them here. You can also use custom CSS effects, server rendering, and high order components. If you prefer to use scroll animation, this framework is for you.

import Fade from 'react-reveal/Fade';

<Fade top>
    <h1>Title</h1>
</Fade>

Let’s take a look at this scrolling animation.

We have 5 blocks, each with a full-screen page and a title inside.

import React, { Component, Fragment } from 'react';
import Fade from 'react-reveal/Fade';

const animateList = [1, 2, 3, 4, 5];

export default class ReactReveal extends Component {
    render() {
        return (
            <Fragment>
                {animateList.map((item, key) => (
                    <div style={styles.block} key={key}>
                        <Fade top>
                            <h1 style={styles.title}>{`block ${item}`}</h1>                       
                        </Fade>
                    </div>
                ))}
            </Fragment>
        );
    }
}

const styles = {
    block: {
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        width: '100%',
        height: '100%',
        background: '#000',
        borderBottom: '1px solid rgba(255,255,255,.2)',
    },
    title: {
        textAlign: 'center',
        fontSize: 100,
        color: '#fff',
        fontFamily: 'Lato, sans-serif',
        fontWeight: 100,
    },
};

We create a constant animateList. This array contains 5 elements. After using the map array method, you can render each element in the components Fadeand insert elements into the header. The styles defined in the constant styleshave short CSS styles for the block and header. We have 5 blocks with animation Fadeon top.

5️. TweenOne and animation in Ant Design

Ant Design is the React UI library, which is a host of easy-to-use components. This is a useful component for creating elegant user interfaces. Ant Design was created by the Chinese conglomerate Alibaba, which uses it in many of its projects.

Let’s look at the animation on their landing page.

As you can see, there are a lot of animated elements. Consider the short version, because all elements have the same animation. Our animation will look like this:

In this animation component is used TweenOne, but he needs PathPluginto set the trajectory. This will work when you put PathPluginin TweenOne.plugins.

TweenOne.plugins.push(PathPlugin);

The main parameters of the animation:

  • duration – animation time in ms;
  • ease – smooth animation;
  • yoyo – alternation of movement forward and backward with each repetition;
  • repeat – repeat animation. Need to use -1for endless animation;
  • p – coordinates of the path for the animation;
  • easePath – coordinates of the smooth path for the animation.

No need to worry about the last two options, more specific for this svg.

const duration = 7000;
const ease = 'easeInOutSine';
const p =
  'M123.5,89.5 C148,82.5 239.5,48.5 230,17.5 C220.5,-13.5 127,6 99.5,13.5 C72,21 -9.5,56.5 1.5,84.5 C12.5,112.5 99,96.5 123.5,89.5 Z';
const easePath =
  'M0,100 C7.33333333,89 14.3333333,81.6666667 21,78 C25.3601456,75.6019199 29.8706084,72.9026327 33,70 C37.0478723,66.2454406 39.3980801,62.0758689 42.5,57 C48,46.5 61.5,32.5 70,28 C77.5,23.5 81.5,20 86.5,16 C89.8333333,13.3333333 94.3333333,8 100,0';
const loop = {
  yoyo: true,
  repeat: -1,
  duration,
  ease,
};

Next, create an animation object. This object has 3 types of animation:

  • redSquare – it has the parameters of the cycle, as well as the Y coordinate, duration and delay;
  • greenBall – has a path with the parameters of the object x, y – the value of p. Duration, repetition and smoothness – TweenOne.easing.path– function with two parameters:
    • path – coordinate easePath;
    • lengthPixel is a curve divided into 400 sections;
  • track – an oval with axes that has a loop style and a rotation parameter.
const animate = {
  redSquare: {
    ...loop,
    y: 15,
    duration: 3000,
    delay: 200,
  },
  greenBall: {
    path: { x: p, y: p },
    duration: 5000,
    repeat: -1,
    ease: TweenOne.easing.path(easePath, { lengthPixel: 400 }),
  },
  track: {
    ...loop,
    rotate: 15,
  },
};

Pay attention to the component TweenOne. Recall in brief, these components will be imported from rc-tween-one. It is used as a base component with basic propsand animated props. This is our animation. Each TweenOnehas its own rules of animation, such as redSquaretrackgreenBall.

import React from 'react';
import TweenOne from 'rc-tween-one';

export default function BannerImage() {
    return (
      <div className="wrapper-ant-design">
        <svg width="482px" height="500px" viewBox="0 0 482 500">
          <defs>
            <path
              d="M151,55 C129.666667,62.6666667 116,74.3333333 110,90 C104,105.666667 103,118.5 107,128.5 L225.5,96 C219.833333,79 209.666667,67 195,60 C180.333333,53 165.666667,51.3333333 151,55 L137,0 L306.5,6.5 L306.5,156 L227,187.5 L61.5,191 C4.5,175 -12.6666667,147.833333 10,109.5 C32.6666667,71.1666667 75,34.6666667 137,0 L151,55 Z"
              id="mask"
            />
          </defs>
          <g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd" transform="translate(0, 30)">
            <g id="Group-13" transform="translate(0.000000, 41.000000)">
              <TweenOne component="g" animation={animate.redSquare}>
                <rect
                  stroke="#F5222D"
                  strokeWidth="1.6"
                  transform="translate(184.000000, 18.000000) rotate(8.000000) translate(-184.000000, -18.000000) "
                  x="176.8"
                  y="150.8"
                  width="14.4"
                  height="14.4"
                  rx="3.6"
                />
              </TweenOne>
            </g>
            <g id="Group-14" transform="translate(150.000000, 230.000000)">
              <g id="Group-22" transform="translate(62.000000, 7.000000)">
                <image
                  id="cc4"
                  alt="globe"
                  xlinkHref="https://gw.alipayobjects.com/zos/rmsportal/FpKOqFadwoFFIZFExjaf.png"
                  width="151px"
                  height="234px"
                />
              </g>
              <mask id="mask-2">
                <use xlinkHref="#mask" fill="white" transform="translate(-42, -33)" />
              </mask>
              <g mask="url(#mask-2)">
                <TweenOne component="g" animation={animate.track} style={{ transformOrigin: '122.7px 58px' }}>
                  <g transform="translate(-16, -52)">
                    <g transform="translate(16, 52)">
                      <path
                        d="M83.1700911,35.9320015 C63.5256194,37.9279025 44.419492,43.1766434 25.8517088,51.6782243 C14.3939956,57.7126276 7.77167019,64.8449292 7.77167019,72.4866248 C7.77167019,94.1920145 61.1993389,111.787709 127.105708,111.787709 C193.012078,111.787709 246.439746,94.1920145 246.439746,72.4866248 C246.439746,55.2822262 212.872939,40.6598106 166.13127,35.3351955"
                        id="line-s"
                        stroke="#0D1A26"
                        strokeWidth="1.35"
                        strokeLinecap="round"
                        transform="translate(127.105708, 73.561453) rotate(-16.000000) translate(-127.105708, -73.561453) "
                      />
                    </g>
                    <TweenOne component="g" animation={animate.greenBall}>
                      <image
                        alt="globe"
                        id="id2"
                        xlinkHref="https://gw.alipayobjects.com/zos/rmsportal/IauKICnGjGnotJBEyCRK.png"
                        x="16"
                        y="62"
                        width="26px"
                        height="26px"
                      />
                    </TweenOne>
                  </g>
                </TweenOne>
              </g>
            </g>
          </g>
        </svg>
      </div>
    );
  }

Looks scary. But in fact, you need to pay attention to these lines.

  <TweenOne component="g" animation={animate.redSquare} />
  <TweenOne component="g" animation={animate.track} />
  <TweenOne component="g" animation={animate.greenBall} />

Animation using this method is quite simple. All that is needed is to describe the rules of the animation and transfer them to the component TweenOne.

Conclusion

Animations for different purposes require different approaches. We reviewed several solutions that you can use in your projects. Choose a method that suits you.

Below you will find a bonus with a list of popular libraries for animation.

ReactJS Libraries

  1. react-motion is a framework that solves animation problems.
  2. react-spring is a physics-based React animation library.
  3. ant-motion – Animate specification and Ant Design components.
  4. react-move – beautiful animations are driven by data for React.
  5. react-flight is the best way to create animation compositions for React.
  6. react-flip-move – simple animation between DOM changes (for example, list ordering) using the FLIP technique.
  7. react-burger-menu is a sidebar component with a collection of effects and styles that use CSS transitions and SVG path animation.
  8. animated – Library of Declarative Animations to React and React Native.
  9. react-tween-state – React animation.
  10. react-animations is a collection of animations for inline-style libraries.

Javascript Libraries

  1. GSAP – ultra high-performance professional animation for the modern Internet.
  2. Anime.js – Anime.js (/ˈæn.ə.meɪ/) is a lightweight JavaScript animation library with a simple but powerful API. Works with CSS, SVG properties, DOM attributes, and JavaScript objects.
  3. Popmotion – simple animation libraries for amazing user interfaces.
  4. vivus is a JavaScript library for drawing animations in SVG.
  5. svg.js is an easy library for managing and animating SVG.
  6. velocity is an animation engine with the same API as jQuery $.animate().
  7. wow – shows animations when scrolling. Friends with animate.css.
  8. dynamic.js is a JavaScript library for creating physics based animations.
  9. granim.js – create smooth and interactive gradient animations using this small Javascript library.
  10. kute.js is an embedded JavaScript animation engine with excellent code quality and good performance.
  11. TweenJs is a simple but powerful interframe filling / animation library for Javascript. Part of the CreateJS library set.
  12. moveTo is an easy JavaScript library of scrolling animation without dependencies.

Use animation wisely!

Get real time updates directly on you device, subscribe now.

Comments
Loading...

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More