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