グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



React-transition-groupでモーダルアニメーションを実装する!

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を用いてモーダルを実装します。

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

このモーダルのアニメーションはオーバーレイとモーダル本体の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を書いて実装するため柔軟性の高いアニメーションを作ることができます。ぜひ使ってみてはいかがでしょうか。

この記事を書いた人

アーティス
アーティス
創造性を最大限に発揮するとともに、インターネットに代表されるITを活用し、みんなの生活が便利で、豊かで、楽しいものになるようなサービスやコンテンツを考え、創り出し提供しています。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします