Мы используем cookies
все статьи

Топ-3 библиотеки для анимации в React

Создать анимацию в React можно многими способами. Например, с помощью методов CSS, но это не серьезно. Если ваша цель — работать со сложной анимацией, лучше изучить специализированные библиотеки и  ...

Создать анимацию в React можно многими способами. Например, с помощью методов CSS, но это не серьезно. Если ваша цель — работать со сложной анимацией, лучше изучить специализированные библиотеки и платформы. В данной статье мы поговорим о самых лучших и популярных трех библиотеках для данной цели.

  1. React Transition Group

Три вещи, которые вы должны знать об этой библиотеке: 

- ReactTransitionGroup меняет классы в случае изменении жизненного цикла компонента. При этом анимированный стиль должен описываться в CSS-классах. 

- ReactTransitionGroup имеет совсем небольшой размер. Его нужно устанавливать в пакете для React-приложения, причём сборка увеличится крайне незначительно. Кроме того, можно применять CDN.

- ReactTransitionGroup включает 3 компонента: CSSTransition, Transition и TransitionGroup. Для запуска анимации достаточно обернуть компонент в них.

Итак, для начала импортируйте CSSTransitionGroup из react-transition-group. Потом оберните список и установите свойство transitionName. Каждый раз, когда в CSSTransitionGroup будет добавляться или удаляться дочерний элемент, он будет получать стили анимации.

<CSSTransitionGroup

    transitionName="example"

>

    {items}

</CSSTransitionGroup>

Обратите внимание, что если установлено свойство transitionName = "example", классы в ваших таблицах стилей должны будут начинаться с имени примера.

.example-enter {

    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;

}

}

Таким образом, вы сможете увидеть базовое использование компонента ReactTransitionGroup. 

Теперь добавим логики. Нужно описать 2 метода для реализации примера списка контактов: 

1) handleAdd — осуществляет добавление новых контактов, получая случайное имя и помещая его непосредственно в массив state.items. (если имя случайное, используется пакет random-name); 

2) handleRemove — контакт удаляется по индексу в массиве 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 });

    }

    handleRemove(i){

        let newItems = this.state.items.slice();

        newItems.splice(i,1);

        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>

        );

    }

};

2. React Animation

React-animations представляет собой библиотеку, основанную на анимациях из animate.css. Библиотека относительно проста в применении и включает в себя множество анимационных коллекций. Сегодня React-animation поддерживает работу с любой inline style-библиотекой, поддерживающей применение объектов для определения ключевых кадров анимации, таких как Aphrodite, Radium либо styled-components.

В первую очередь, импортируем анимацию, выбранную из react-animations.

После создания компонента обернем любой HTML-код либо компонент для выполнения анимации.

Пример кода:

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>

        );

    }

}

3. React Move

Библиотека для создания красивых анимаций, управляемых данными React. Позволяет определять анимацию с помощью функций длительности, задержки и легкости. 

Особенности: 

  • анимация HTML, SVG React-Native;

  • события жизненного цикла анимации: начало, прерывание, конец;

  • пользовательские функции переключения;

  • документация с множеством примеров;

  • поддерживается в React, React-Native, React-VR;

  • совместимость с TypeScript.

Пример кода с официального демо данной библиотеки:

import React, { PureComponent } from 'react'

import { NodeGroup } from 'react-move'

import Surface from 'docs/src/components/Surface' // this is just a responsive SVG

import { scaleLinear, scaleBand } from 'd3-scale'

import { easeExpInOut } from 'd3-ease'

import { ascending, max } from 'd3-array'

// **************************************************

//  SVG Layout

// **************************************************

const view = [1000, 450] // [width, height]

const trbl = [10, 10, 30, 10] // [top, right, bottom, left] margins

const dims = [ // Adjusted dimensions [width, height]

  view[0] - trbl[1] - trbl[3],

  view[1] - trbl[0] - trbl[2],

]

// **************************************************

//  Mock Data

// **************************************************

const letters = [

  { letter: 'A', frequency: 0.08167 },

  { letter: 'B', frequency: 0.01492 },

  { letter: 'C', frequency: 0.02780 },

  { letter: 'D', frequency: 0.04253 },

  { letter: 'E', frequency: 0.12702 },

  { letter: 'F', frequency: 0.02288 },

  { letter: 'G', frequency: 0.02022 },

  { letter: 'H', frequency: 0.06094 },

  { letter: 'I', frequency: 0.06973 },

  { letter: 'J', frequency: 0.00153 },

  { letter: 'K', frequency: 0.00747 },

  { letter: 'L', frequency: 0.04025 },

  { letter: 'M', frequency: 0.02517 },

  { letter: 'N', frequency: 0.06749 },

  { letter: 'O', frequency: 0.07507 },

  { letter: 'P', frequency: 0.01929 },

  { letter: 'Q', frequency: 0.00098 },

  { letter: 'R', frequency: 0.05987 },

  { letter: 'S', frequency: 0.06333 },

  { letter: 'T', frequency: 0.09056 },

  { letter: 'U', frequency: 0.02758 },

  { letter: 'V', frequency: 0.01037 },

  { letter: 'W', frequency: 0.02465 },

  { letter: 'X', frequency: 0.00150 },

  { letter: 'Y', frequency: 0.01971 },

  { letter: 'Z', frequency: 0.00074 },

]

const y = scaleLinear()

  .range([dims[1], 0])

  .domain([0, max(letters, (d) => d.frequency)])

class Example extends PureComponent {

  state = {

    sortAlpha: true,

  }

  update = () => {

    this.setState((state) => ({

      sortAlpha: !state.sortAlpha,

    }))

  }

  render() {

    const { sortAlpha } = this.state

    const sorted = letters.sort(sortAlpha ?

      (a, b) => ascending(a.letter, b.letter) :

      (a, b) => b.frequency - a.frequency,

    ).slice(0)

    const scale = scaleBand()

      .rangeRound([0, dims[0]])

      .domain(sorted.map((d) => d.letter))

      .padding(0.1)

    const width = scale.bandwidth()

    return (

      <div style={{ width: '100%' }}>

        <button onClick={this.update}>

          {`Sort ${sortAlpha ? 'Value' : 'Alpha'}`}

        </button>

        <Surface view={view} trbl={trbl}>

          <NodeGroup

            data={sorted}

            keyAccessor={(d) => d.letter}

        start={() => ({

              opacity: 1e-6,

              x: 1e-6,

            })}

            enter={(d) => ({

              opacity: [0.7],

              x: [scale(d.letter)],

              timing: { duration: 750, ease: easeExpInOut },

            })}

            update={(d, i) => ({

              opacity: [0.7],

              x: [scale(d.letter)],

              timing: { duration: 750, delay: i * 50, ease: easeExpInOut },

            })}

            leave={() => ({

              opacity: [1e-6],

              x: [scale.range()[1]],

              timing: { duration: 750, ease: easeExpInOut },

            })}

          >

            {(nodes) => (

              <g>

                {nodes.map(({ key, data, state: { x, opacity } }) => (

                  <g key={key} transform={`translate(${x},0)`}>

                    <rect

                      height={dims[1] - y(data.frequency)}

                      y={y(data.frequency)}

                      fill="#ff69b4"

                      width={width}

                      opacity={opacity}

                    />

                    <text

                      x={scale.bandwidth() / 2}

                      y={dims[1] + 15}

                      dx="-.35em"

                      fill="#dadada"

                    >{data.letter}</text>

                  </g>

                ))}

              </g>

            )}

          </NodeGroup>

        </Surface>

      </div>

    )

  }

}

export default Example

Таким образом, в данной статье мы разобрали одни из лучших библиотек для реализации анимаций в React, узнали об их ключевых особенностях и возможностях их применения, а также научились внедрять данные технологии в свои проекты.

Alena L.
Alena L.
August 24, 2022#tech
другие статьи
Questions that you should ask the employer at the interview

Прежде всего нужно понимать, что собеседование - это не д...

читать
читать
Why is it important to develop emotional intelligence

В разное время основными факторами развития бизнеса были ...

читать
читать
Websocket API on NodeJS

В данной статье мы рассмотрим технологию Websocket для ра...

читать
читать
Habits that prevent you from growing in your career

Одной из важнейших мотиваций любого сотрудника является к...

читать
читать