ReactJS - 动画



动画是现代 Web 应用的一个令人兴奋的功能。它给应用程序带来了一种焕然一新的感觉。React 社区提供了许多优秀的基于 React 的动画库,例如 React Motion、React Reveal、react-animations 等。React 本身早些时候也提供了一个动画库,即 React Transition Group 作为附加选项。它是一个独立的库,增强了该库的早期版本。让我们在本节中学习 React Transition Group 动画库。

React Transition Group

React Transition Group 库是一个简单的动画实现。它本身不执行任何动画。相反,它公开了与核心动画相关的信息。每个动画基本上都是一个元素从一个状态到另一个状态的转换。该库公开了每个元素的尽可能少的最小状态,如下所示:

  • 进入
  • 已进入
  • 退出
  • 已退出

该库提供了为每个状态设置 CSS 样式并根据样式在元素从一个状态移动到另一个状态时对元素进行动画处理的选项。该库在 props 中提供了设置元素当前状态的选项。如果 in props 值为 true,则表示该元素正在从 进入 状态移动到 退出 状态。如果 in props 值为 false,则表示该元素正在从退出状态移动到已退出状态。

安装

要安装此 React Transition Group 库,请使用以下命令之一:

# npm
npm install react-transition-group --save

# yarn
yarn add react-transition-group

Transition

TransitionReact Transition Group 提供的基本组件,用于对元素进行动画处理。让我们创建一个简单的应用程序,并尝试使用 Transition 元素淡入/淡出一个元素。

首先,使用 Create React AppRollup 捆绑器创建一个新的 React 应用程序 react-animation-app,方法是按照创建 React 应用程序章节中的说明进行操作。

接下来,安装 React Transition Group 库。

cd /go/to/project 
npm install react-transition-group --save

接下来,在您喜欢的编辑器中打开应用程序。

接下来,在应用程序的根目录下创建 src 文件夹。

接下来,在 src 文件夹下创建 components 文件夹。

接下来,在 src/components 文件夹下创建一个文件 HelloWorld.js 并开始编辑。

接下来,导入 React 和动画库。

import React from 'react'; 
import { Transition } from 'react-transition-group'

接下来,创建 HelloWorld 组件。

class HelloWorld extends React.Component {
   constructor(props) {
      super(props);
   }
}

接下来,在构造函数中将转换相关的样式定义为 JavaScript 对象。

this.duration = 2000;
this.defaultStyle = {
   transition: `opacity ${this.duration}ms ease-in-out`,
   opacity: 0,
}
this.transitionStyles = {
   entering: { opacity: 1 },
   entered: { opacity: 1 },
   exiting: { opacity: 0 },
   exited: { opacity: 0 },
};

这里,

  • defaultStyles 设置转换动画

  • transitionStyles 设置各种状态的样式

接下来,在构造函数中设置元素的初始状态。

this.state = { 
   inProp: true 
}

接下来,通过每 3 秒更改一次 inProp 值来模拟动画。

setInterval(() => {
   this.setState((state, props) => {
      let newState = {
         inProp: !state.inProp
      };
      return newState;
   })
}, 3000);

接下来,创建一个 render 函数。

render() { 
   return ( 
   ); 
}

接下来,添加 Transition 组件。将 this.state.inProp 用于 in prop,将 this.duration 用于 timeout prop。Transition 组件需要一个函数,该函数返回用户界面。它基本上是一个 Render props

render() {
   return (
      <Transition in={this.state.inProp} timeout={this.duration}>
         {state => ({
            ... component's user interface.
         })
      </Transition>
   );
}

接下来,在容器内编写组件的用户界面,并为容器设置 defaultStyletransitionStyles

render() {
   return (
      <Transition in={this.state.inProp} timeout={this.duration}>
         {state => (
            <div style={{
               ...this.defaultStyle,
               ...this.transitionStyles[state]
            }}>
               <h1>Hello World!</h1>
            </div>
         )}
      </Transition>
   );
}

最后,公开组件。

export default HelloWorld

组件的完整源代码如下:

import React from "react";
import { Transition } from 'react-transition-group';

class HelloWorld extends React.Component {
   constructor(props) {
      super(props);
      this.duration = 2000;
      this.defaultStyle = {
         transition: `opacity ${this.duration}ms ease-in-out`,
         opacity: 0,
      }
      this.transitionStyles = {
         entering: { opacity: 1 },
         entered: { opacity: 1 },
         exiting: { opacity: 0 },
         exited: { opacity: 0 },
      };
      this.state = {
         inProp: true
      }
      setInterval(() => {
         this.setState((state, props) => {
            let newState = {
               inProp: !state.inProp
            };
            return newState;
         })
      }, 3000);
   }
   render() {
      return (
         <Transition in={this.state.inProp} timeout={this.duration}>
            {state => (
               <div style={{
                  ...this.defaultStyle,
                  ...this.transitionStyles[state]
               }}>
                  <h1>Hello World!</h1>
               </div>
            )}
         </Transition>
      );
   }
}
export default HelloWorld;

接下来,在 src 文件夹下创建一个文件 index.js 并使用 HelloWorld 组件。

import React from 'react';
import ReactDOM from 'react-dom';
import HelloWorld from './components/HelloWorld';

ReactDOM.render(
   <React.StrictMode   
      <HelloWorld /   
   </React.StrictMode   ,
   document.getElementById('root')
);

最后,在根文件夹下创建一个 public 文件夹并创建 index.html 文件。

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta charset="utf-8">
      <title>React Containment App</title>
   </head>
   <body>
      <div id="root"></div>
      <script type="text/JavaScript" src="./index.js"></script>
   </body>
</html>

接下来,使用 npm 命令提供服务。

npm start

接下来,打开浏览器并在地址栏中输入 https://127.0.0.1:3000 并按回车键。

单击删除链接将从 redux 存储中删除该项目。

Animation

要了解有关使用 React Transition Group 对元素进行动画处理的更多信息,请单击 此处

CSSTransition

CSSTransition 构建在 Transition 组件之上,它通过引入 classNames prop 来改进 Transition 组件。classNames prop 指的是用于元素各种状态的 css 类名。

例如,classNames=hello prop 指的是以下 css 类。

.hello-enter {
   opacity: 0;
}
.hello-enter-active {
   opacity: 1;
   transition: opacity 200ms;
}
.hello-exit {
   opacity: 1;
}
.hello-exit-active {
   opacity: 0;
   transition: opacity 200ms;
}

让我们使用 CSSTransition 组件创建一个新的组件 HelloWorldCSSTransition

首先,在您喜欢的编辑器中打开我们的 react-animation-app 应用程序

接下来,在 src/components 文件夹下创建一个新文件 HelloWorldCSSTransition.css 并输入转换类。

.hello-enter {
   opacity: 1;
   transition: opacity 2000ms ease-in-out;
}
.hello-enter-active {
   opacity: 1;
   transition: opacity 2000ms ease-in-out;
}
.hello-exit {
   opacity: 0;
   transition: opacity 2000ms ease-in-out;
}
.hello-exit-active {
   opacity: 0;
   transition: opacity 2000ms ease-in-out;
}

接下来,在 src/components 文件夹下创建一个新文件 HelloWorldCSSTransition.js 并开始编辑。

接下来,导入 React 和动画库。

import React from 'react'; 
import { CSSTransition } from 'react-transition-group'

接下来,导入 HelloWorldCSSTransition.css

import './HelloWorldCSSTransition.css'

接下来,创建 HelloWorld 组件。

class HelloWorldCSSTransition extends React.Component {
   constructor(props) {
      super(props);
   }
}

接下来,在构造函数中定义转换的持续时间。

this.duration = 2000;

接下来,在构造函数中设置元素的初始状态。

this.state = { 
   inProp: true 
}

接下来,通过每 3 秒更改一次 inProp 值来模拟动画。

setInterval(() => {
   this.setState((state, props) => {
      let newState = {
         inProp: !state.inProp
      };
      return newState;
   })
}, 3000);

接下来,创建一个 render 函数。

render() { 
   return (
   ); 
}

接下来,添加 CSSTransition 组件。将 this.state.inProp 用于 in prop,将 this.duration 用于 timeout prop,将 hello 用于 classNames prop。CSSTransition 组件需要用户界面作为子 prop。

render() {
   return (
      <CSSTransition in={this.state.inProp} timeout={this.duration} 
         classNames="hello">
         // ... user interface code ...   
      </CSSTransition>
   );
}

接下来,编写组件的用户界面。

render() {
   return (
       <CSSTransition in={this.state.inProp} timeout={this.duration} 
      classNames="hello">
      <div>
          <h1>Hello World!</h1>
      </div>
       </CSSTransition>
   );
}

最后,公开组件。

export default HelloWorldCSSTransition;

组件的完整源代码如下:

import React from 'react';
import { CSSTransition } from 'react-transition-group'
import './HelloWorldCSSTransition.css' 

class HelloWorldCSSTransition extends React.Component {
   constructor(props) {
      super(props);
      this.duration = 2000;
      this.state = {
         inProp: true
      }
      setInterval(() => {
         this.setState((state, props) => {
            let newState = {
               inProp: !state.inProp
            };
            return newState;
         })
      }, 3000);
   }
   render() {
      return (
         <CSSTransition in={this.state.inProp} timeout={this.duration} 
            classNames="hello">
            <div>
               <h1>Hello World!</h1>
            </div>
         </CSSTransition>
      );
   }
}
export default HelloWorldCSSTransition;

接下来,在 src 文件夹下创建一个文件 index.js 并使用 HelloWorld 组件。

import React from 'react';
import ReactDOM from 'react-dom';
import HelloWorldCSSTransition from './components/HelloWorldCSSTransition';

ReactDOM.render(
   <React.StrictMode>
      <HelloWorldCSSTransition />
   </React.StrictMode>,
   document.getElementById('root')
);

接下来,使用 npm 命令提供服务。

npm start

接下来,打开浏览器并在地址栏中输入 https://127.0.0.1:3000 并按回车键。

每 3 秒,消息将淡入和淡出。

Animation

TransitionGroup

TransitionGroup 是一个容器组件,它在一个列表中管理多个转换组件。例如,当列表中的每个项目使用 CSSTransition 时,可以使用 TransitionGroup 将所有项目组合在一起以进行正确的动画处理。

<TransitionGroup>
   {items.map(({ id, text }) => (
      <CSSTransition key={id} timeout={500} classNames="item" >
         <Button
            onClick={() =>
               setItems(items =>
                  items.filter(item => item.id !== id)
               )
            }
            >
            &times;
         </Button>
         {text}
      </CSSTransition>
   ))}
</TransitionGroup>
广告