LoginSignup
0
0

More than 1 year has passed since last update.

[ReactTransitionGroup]ハンズオン!モーダルアニメーションを実装する!

Posted at

ReactでCSSアニメーションを扱うためのライブラリを紹介していきます。

React-transition-groupとは

アニメーションそのものを提供しているのではなく、CSSをDOMに反映するタイミングを管理してアニメーションを実現するライブラリとなっています。そして4つのコンポーネントが用意されています。

  • Transition
  • CSSTransition
  • SwitchTransition
  • TransitionGroup

作りたいアニメーションによって使い分ける必要があります。

公式

インストール

# npm
npm install react-transition-group

# yarn
yarn add react-transition-group

モーダルを実装

今回はCSSTransitionとStyledComponentを用いてモーダルを実装します。

実際の挙動がこちらです。

modal.gif

このモーダルのアニメーションはオーバーレイとモーダル本体の2つで構成されています。オーバーレイはフェードインとフェードアウト、一方モーダル本体はフェードインとフェードアウトに加え拡大縮小が含まれています。

それではコードを見ていきましょう。

import './App.css';
import {CSSTransition} from "react-transition-group";
import {useState} from "react";
import styled from "styled-components";

export const App = () => {
  const [isOpen, switchIsOpen] = useState(false)

  return (
    <>
      <TransitionStyle>
        <div className="open" onClick={() => switchIsOpen(true)}>開く</div>
        <div className="modal-wrapper">
          <CSSTransition
            classNames="modal"
            in={isOpen}
            timeout={700}
            unmountOnExit>
            <ModalStyle>
              <div className="content">
                モーダルです。
              </div>
              <div className="close" onClick={() => switchIsOpen(false)}>閉じる</div>
            </ModalStyle>
          </CSSTransition>
        </div>
        <CSSTransition
          classNames="overlay"
          in={isOpen}
          timeout={700}
          unmountOnExit>
          <OverlayStyle/>
        </CSSTransition>
      </TransitionStyle>
    </>
  );
}

export default App

// transitionのスタイル
const TransitionStyle = styled.div`
  .open{
    cursor: pointer;
    font-size: 40px;  
    font-weight: bold;
  }

  .modal-wrapper{
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);

    .modal-enter {
      opacity: 0;
      transform: scale(0.9);
    }

    .modal-enter-active {
      opacity: 1;
      transform: translateX(0);
      transition: opacity 0.3s, transform 0.3s;
    }

    .modal-exit {
      opacity: 1;
    }

    .modal-exit-active {
      opacity: 0;
      transition: opacity 0.3s, transform 0.3s;
      transform: scale(0.9);
    }
  }

  .overlay-enter {
    opacity: 0;
  }

  .overlay-enter-active {
    opacity: 1;
    transform: translateX(0);
    transition: opacity 0.3s, transform 0.3s;
  }

  .overlay-exit {
    opacity: 1;
  }

  .overlay-exit-active {
    opacity: 0;
    transition: opacity 0.3s, transform 0.3s;
  }
`;

// モーダルのスタイル
const ModalStyle = styled.div`
  padding: 100px;
  background-color: #ffffff;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  .content{
    font-size: 40px;
    font-weight: bold;
  }

  .close{
    cursor: pointer;
    margin: 50px 0 0;
  }
`

// オーバーレイのスタイル
const OverlayStyle = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
`;

オーバーレイとモーダル本体で使用したCSSTransitionのプロパティは同じなので、モーダル本体を例に挙げ解説します。

inは表示非表示を切り替えるためのステートを渡します。

timeoutはアニメーションの開始から終了までの時間です。

最後のunmountOnExitはアニメーションが終了した時にCSSTransitionをアンマウントさせることができます。

そしてCSSTransitionにchildrenで渡しているのがモーダル本体です。オーバーレイも同様です。

<CSSTransition
  classNames="modal"
  in={isOpen}
  timeout={700}
  unmountOnExit>
  <ModalStyle>
    <div className="content">
      モーダルです。
    </div>
    <div className="close" onClick={() => switchIsOpen(false)}>閉じる</div>
  </ModalStyle>
</CSSTransition>

classNamesに渡した文字列が、アニメーションのクラス名のプレフィックスになります。


classNames="modal"

アニメーション開始時のクラス名="modal-enter"
アニメーション中のクラス名="modal-enter-active"
アニメーション終了時のクラス名="modal-exit"
アニメーション中のクラス名="modal-exit-active"

上記のクラス名を使用したコードです。

.modal-enter {
  opacity: 0;
  transform: scale(0.9);
}

.modal-enter-active {
  opacity: 1;
  transform: translateX(0);
  transition: opacity 0.3s, transform 0.3s;
}

.modal-exit {
  opacity: 1;
}

.modal-exit-active {
  opacity: 0;
  transition: opacity 0.3s, transform 0.3s;
  transform: scale(0.9);
}

モーダルの切り替えステートをtrueにするとmodal-enterのスタイルでマウントされ、modal-enter-activeのスタイルに切り替わります。

falseにするとmodal-exitのスタイルが適応され、modal-exit-activeに切り替わりアンマウントされるという流れになります。

まとめ

モーダル以外にも他のコンポーネントを用いて様々な動きのアニメーションを実装することができます。自分でcssを書いて実装するため柔軟性の高いアニメーションを作ることができます。ぜひ使ってみてはいかがでしょうか。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0