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://: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://: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>
廣告