iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

用30天更加認識 React.js 這個好朋友系列 第 20

Day20-React 簡易動畫篇-上篇

這篇要來介紹一下一些能用 React 實現一些動畫效果的函式庫,首先介紹的就是本篇的主角 React Transition Group,

React Transition Group 目前有四種元件,分別是:

  • Transition
  • CSSTransition
  • SwitchTransition
  • TransitionGroup

接著我們來一一介紹它們吧!

Transition 元件

使用這個元件可以透過一些 api 去訂閱元件的狀態,常用在 mount 和 unmount 過渡動畫的元件。

此元件有四種狀態:

  • entering
  • entered
  • exiting
  • exited

至於改變 Transition 元件的狀態是透過 in 這個 props 屬性。

in 為 true 時,會從 entering 改變到 entered
in 為 false 時,會從 exiting 改變到 exited

當然除了 in 這個 props 屬性外還有其他的屬性,可以參考官方文件,這裡就不一一介紹。

Transition 元件範例

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

const duration = 300;

const defaultStyle = {
  transition: `opacity ${duration}ms ease-in-out`,
  opacity: 0,
  padding: 20,
  display: "inline-block",
  backgroundColor: "#8787d8"
};

const transitionStyles = {
  entering: { opacity: 0 },
  entered: { opacity: 1 }
};

const Fade = ({ in: inProp }) => (
  <Transition in={inProp} timeout={duration}>
    {(state) => (
      <div
        style={{
          ...defaultStyle,
          ...transitionStyles[state]
        }}
      >
        I'm A fade Transition!
      </div>
    )}
  </Transition>
);

export default function App() {
  const [show, setShow] = useState(false);

  const handleToggle = () => setShow(!show);

  return (
    <>
      <button onClick={() => handleToggle()}>Click to toggle</button>
      <Fade in={!!show} />
    </>
  );
}

範例程式碼

CSSTransition 元件

這個元件除了具有 Transition 元件的功能外,可以根據狀態(appear、enter、exit)去切換不同的 className,進而改變樣式。

appear 狀態: 為 false 時當 CSSTransition 元件加載完畢後不執行動畫,為 true 時元件加載完畢則立即執行動畫。
如果要元件初次渲染就有動畫,則需要設成 true。

常見的 className 設定有以下幾種,記得 CSSTransition 元件要設定對應的 className 開頭(以下範例就是 classNames="example") :

/* in 為 true 時: */
.example-enter {
/*   opacity: 0; */
}
.example-enter-active {
/*   opacity: 1; */
/*   transition: opacity 200ms; */
}

/* in 為 false 時: */
.example-exit {
/*   opacity: 1; */
}
.example-exit-active {
/*   opacity: 0; */
/*   transition: opacity 200ms; */
}
<CSSTransition
  in={showMessage}
  timeout={300}
  classNames="example"
  unmountOnExit
  onEnter={() => setShowButton(false)}
  onExited={() => setShowButton(true)}
>
  <!-- ... -->
</CSSTransition>

CSSTransition 元件範例:

// App.js
import React, { useState, useEffect } from "react";
import { CSSTransition } from "react-transition-group";

import "./styles.css";

const Fade = ({ children, ...props }) => (
  <CSSTransition {...props} timeout={1000} classNames="fade">
    {children}
  </CSSTransition>
);

export default function App() {
  const [show, setShow] = useState(false);

  useEffect(() => {
    let id = setInterval(() => {
      setShow(!show);
    }, 5000);

    return () => clearInterval(id);
  }, [show]);

  return (
    <Fade in={show}>
      <div className="greeting">Hello world</div>
    </Fade>
  );
}
/* styles.css */
.fade-enter {
  opacity: 0.01;
}

.fade-enter.fade-enter-active {
  opacity: 1;
  transition: opacity 1000ms ease-in;
}

.fade-exit {
  opacity: 1;
}

.fade-exit.fade-exit-active {
  opacity: 0.01;
  transition: opacity 800ms ease-in;
}

.greeting {
  padding: 20px;
  background-color: #ccc;
  width: 200px;
  margin: auto;
  text-align: center;
  border-radius: 4px;
}

範例程式碼

這篇先到這邊結束,下篇將會介紹剩下的兩個元件,以下補充一些相關連結。

其他補充

React Transition Group 官網

React-Motion

除了 React Transition Group,React-Motion 也是相當不錯的 React 動畫函式庫!


上一篇
Day19-React Router 篇-下篇
下一篇
Day21-React 簡易動畫篇-下篇
系列文
用30天更加認識 React.js 這個好朋友32

尚未有邦友留言

立即登入留言