Share This
Связаться со мной
Крути в низ
Categories
//5 современных способов создания анимации в React

5 современных способов создания анимации в React

Перевод статьи «5 Ways to animate a React app»

Иван Капцов

Создание анимации в приложении React — популярная тема. Многие разработчики анимируют только с помощью CSS, добавляя классы в теги HTML. Это отличный способ, но если хотите создавать сложные анимации, обратите внимание на другие подходы.

Давайте поговорим о них.

Примечание: весь код из статьи вы можете найти в этом репозитории.

1. Метод CSS

Это один из лучших методов для простой анимации. Если вы используете его вместо импорта библиотек JavaScript, сборка остаётся маленькой и браузер тратит меньше ресурсов. Это сильно влияет на производительность приложений. Если у вас простая анимация и вы беспокоитесь о размере своей сборки, обратите внимание на этот метод.

Давайте посмотрим на пример гамбургер-меню:

5 sovremennyh sposobov sozdanija animacii v react 2fd9c57 - 5 современных способов создания анимации в React

Это простое меню со свойством css и триггером className = "is-nav-open" для тега html. Способов реализации много. Один из них — создать wrapper над навигацией и вызывать изменения полей. Навигация имеет постоянную ширину, равную 250px, и wrapper со свойством margin-left или translateX с той же шириной. Если нужно показать навигацию, следует добавить className = "is-nav-open" для wrapper и переместить wrapper на margin-left / translateX: 0;

import React, {Component} from 'react'; import {Icon} from 'antd'; import './style.css';  export default class ExampleCss extends Component {     constructor(props){         super(props);         this.wrapperRef = React.createRef();     }     handleClick() {         const wrapper = this.wrapperRef.current;         wrapper.classList.toggle('is-nav-open')     }     render() {         return (             <div ref={this.wrapperRef} 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>         );     } }

И CSS стили:

.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: 100%;     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; }

Этот метод необходим в большинстве случаев. Лучше написать несколько строк CSS и изменять className, чем импортировать и использовать большие библиотеки. А пользователи будут благодарны за то, что приложение быстро работает в браузере.

React: практики, которые помогут стать продвинутым разработчикомtproger.ru

2. ReactTransitionGroup

Этот дополнительный компонент был разработан парнями из сообщества ReactJs. ReactTransitionGroup легко реализует базовые CSS-анимации и переходы.

Вебинар «Разработка библиотеки компонентов на React + Storybook»

22 сентября в 20:00, Онлайн, Беcплатно

tproger.ru События и курсы на tproger.ru

Разработчики описывают эту библиотеку так:

Набор компонентов для управления состояниями с течением времени, специально разработанный для анимаций.

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

  1. ReactTransitionGroup меняет классы при изменении жизненного цикла компонента. Анимированный стиль, в свою очередь, должен быть описан в классах CSS.
  2. ReactTransitionGroup имеет небольшой размер. Он должен быть установлен в пакете для React приложения и несущественно увеличит вашу сборку. Также можно использовать CDN.
  3. ReactTransitionGroup имеет 3 компонента (Transition, CSSTransition и TransitionGroup). Чтобы запустить анимацию, нужно обернуть компонент в них.

Посмотрим, как сделать похожую анимацию.

5 sovremennyh sposobov sozdanija animacii v react 713ba32 - 5 современных способов создания анимации в React

Сначала нужно импортировать 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.

Конечно, надо добавить немного логики. Следует описать два метода для реализации нашего примера списка контактов:

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

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>         );     } };

3️. React-animations

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

Можете посмотреть на анимации в гифке:

5 sovremennyh sposobov sozdanija animacii v react 0634351 - 5 современных способов создания анимации в React

 

Давайте посмотрим, как это работает. Например, анимация подпрыгивания.

5 sovremennyh sposobov sozdanija animacii v react c7bae68 - 5 современных способов создания анимации в React

Сначала нужно импортировать выбранную анимацию из react-animations.

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

Когда компонент создан, нужно обернуть любой HTML-код или компонент для анимации.

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

Пример:

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>         );     } }

Анимация работает. Она базовая и очень простая.

Есть хорошее решение для использования этой анимации при прокрутке — react-animate-on-scroll.

4️. React-reveal

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

import Fade from 'react-reveal/Fade';  <Fade top>     <h1>Title</h1> </Fade>

Давайте посмотрим на эту анимацию прокрутки.

5 sovremennyh sposobov sozdanija animacii v react 900f00b - 5 современных способов создания анимации в React

У нас есть 5 блоков, у каждого из которых полноэкранная страница и заголовок внутри.

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,     }, };

Мы создаём константу animateList. Этот массив содержит 5 элементов. После использования метода массива map вы можете рендерить каждый элемент в компонентах Fade и вставить элементы в заголовок. Стили, определённые в константе styles, имеют короткие стили CSS для блока и заголовка. У нас есть 5 блоков с анимацией Fade сверху.

5️. TweenOne и анимация в Ant Design

Ant Design — это библиотека React UI, представляющая собой множество простых в использовании компонентов. Это полезный компонент для создания элегантных пользовательских интерфейсов. Ant Design создан китайским конгломератом Alibaba, который использует его во многих своих проектах.

Давайте рассмотрим анимацию на их лендинге.

5 sovremennyh sposobov sozdanija animacii v react ed1501b - 5 современных способов создания анимации в React

Как видите, здесь много анимированных элементов. Рассмотрим короткую версию, потому что у всех элементов одинаковая анимация. Наша анимация будет выглядеть так:

5 sovremennyh sposobov sozdanija animacii v react aefbfd4 - 5 современных способов создания анимации в React

В этой анимации использован компонент TweenOne, но ему нужен PathPlugin для задания траектории. Это будет работать, когда вы поместите PathPlugin в TweenOne.plugins.

TweenOne.plugins.push(PathPlugin);

Основные параметры анимации:

  • duration — время анимации в мс;
  • ease — плавность анимации;
  • yoyo — чередование движения вперёд и назад с каждым повторением;
  • repeat — повтор анимации. Нужно использовать -1 для бесконечной анимации;
  • p — координаты пути для анимации;
  • easePath — координаты плавного пути для анимации.

Не нужно беспокоиться о последних двух параметрах, более специфичных для данного 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, };

Далее создадим объект анимации. Этот объект имеет 3 типа анимации:

  • redSquare — в нём есть параметры цикла, а также координата Y, длительность и задержка;
  • greenBall — имеет путь с параметрами объекта x, y — значение p. Длительность, повтор и плавность — TweenOne.easing.path — функция с двумя параметрами:
    • path — координата easePath;
    • lengthPixel — кривая, разделённая на 400 секций;
  • track — овал с осями, который имеет стили цикла и параметр поворота.
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,   }, };

Обратите внимание на компонент TweenOne. Напомним вкратце, эти компоненты будут импортированы из rc-tween-one. Он используется в качестве базового компонента с базовыми props и анимационными props. Это и есть наша анимация. Каждый TweenOne имеет свои собственные правила анимации, такие как redSquare, track, greenBall.

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>     );   }

5 sovremennyh sposobov sozdanija animacii v react 4995e9c - 5 современных способов создания анимации в React

Выглядит пугающе. Но на самом деле нужно обратить внимание на эти строки.

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

Анимировать с помощью этого метода довольно просто. Всё, что нужно, это описать правила анимации и перенести их в компонент TweenOne.

Заключение

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

 

Ниже вы найдёте бонус со списком популярных библиотек для анимации.

Библиотеки ReactJs

  1. react-motion — фреймворк, который решает проблемы с анимацией.
  2. react-spring — основанная на физике библиотека анимации React.
  3. ant-motion — спецификация Animate и компоненты Ant Design.
  4. react-move — красивые анимации, управляемые данными для React.
  5. react-flight — лучший способ создания анимационных композиций для React.
  6. react-flip-move — простая анимация между изменениями DOM (например, упорядочивание списка) с использованием техники FLIP.
  7. react-burger-menu — компонент боковой панели с коллекцией эффектов и стилей, использующих переходы CSS и анимацию пути SVG.
  8. animated — Библиотека Декларативных Анимаций для React и React Native.
  9. react-tween-state — анимация React.
  10. react-animations — коллекция анимаций для inline-style библиотек.

Библиотеки Javascript

  1. GSAP — ультра высокопроизводительная профессиональная анимация для современного Интернета.
  2. Anime.js — Anime.js (/ˈæn.ə.meɪ/) — это лёгкая библиотека анимации JavaScript с простым, но мощным API. Работает со свойствами CSS, SVG, атрибутами DOM и объектами JavaScript.
  3. Popmotion — простые библиотеки анимации для восхитительных пользовательских интерфейсов.
  4. vivus — библиотека JavaScript для рисования анимации в SVG.
  5. svg.js — лёгкая библиотека для управления и анимации SVG.
  6. velocity — это анимационный движок с тем же API, что и у jQuery $.animate().
  7. wow — показывает анимации при прокрутке. Дружит с animate.css.
  8. dynamic.js — библиотека JavaScript для создания анимации на основе физики.
  9. granim.js — создавайте плавные и интерактивные градиентные анимации с помощью этой небольшой библиотеки Javascript.
  10. kute.js — это встроенный движок JavaScript-анимации с отличным качеством кода и хорошей производительностью.
  11. TweenJs — простая, но мощная библиотека межкадрового заполнения / анимации для Javascript. Часть набора библиотек CreateJS.
  12. moveTo — лёгкая JavaScript библиотека анимации прокрутки без зависимостей.

Используйте анимацию с умом!

***

Спасибо за внимание! Занимайтесь тем, что вам нравится, продолжайте учиться и не прекращайте кодить.

А если вам понравилась статья, подписывайтесь на автора на Medium и LinkedIn.

Создание анимации на базе JavaScript с помощью библиотеки Anime.js. Часть 1tproger.ru

Хинт для программистов: если зарегистрируетесь на соревнования Huawei Honor Cup, бесплатно получите доступ к онлайн-школе для участников. Можно прокачаться по разным навыкам и выиграть призы в самом соревновании.

Перейти к регистрации

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Свежие комментарии

    Рубрики

    About Author 01.

    Roman Spiridonov
    Roman Spiridonov

    Привет ! Мне 38 лет, я работаю в области информационных технологий более 4 лет. Тут собрано самое интересное.

    Our Instagram 04.

    Categories 05.

    © Speccy 2020 / All rights reserved

    Связаться со мной
    Close