React

[React] Framer Motion(4) AnimatePresence 사용법 및 슬라이드 구현

cob 2022. 10. 2. 21:48
라이브러리 설치 및 기본 사용 법은 아래 링크에서 확인
https://cocococo.tistory.com/29

 

AnimatePresence 

 

 

AnimatePresence 란?
elemet가 나타나거나 사라질 경우 애니메이션 효과 발생시키는 컴포넌트이다.
자연스러운 show / hide의 애니메이션 효과를 부여한다.
* AnimatePresence의 규칙 *
1. visible상태여야 한다.
2.내부에는 조건문이 있어야 한다.

 

 


1. AnimatePresence를 사용한 Show / Hide 구현

import { motion, AnimatePresence } from "framer-motion";
import { useState } from "react";
import styled from "styled-components";

const Wrapper = styled(motion.div)`
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
`;

const Box = styled(motion.div)`
  margin-top: 100px;
  width: 400px;
  height: 200px;
  background-color: rgba(255, 255, 255, 1);
  border-radius: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 28px;
  box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
  position: absolute; // 부모 기준으로 배치하기 때문에 슬라이드가 튀지 않는다
  top: 10px;
`;

const boxVariants = {
  initial: { opacity: 0, scale: 0 },
  visible: { opacity: 1, scale: 1, rotateZ: 360 },
  leaving: { opacity: 0, scale: 0, y: 50 },
};

function App() {
  const [showing, setShowing] = useState(false);
  const toggleShowing = () => setShowing((prev) => !prev);
  return (
    <Wrapper>
      <button onClick={toggleShowing}>Click</button>
      <AnimatePresence>
        {showing ? (
          <Box
            variants={boxVariants}
            initial="initial"
            animate="visible"
            exit="leaving"
          />
        ) : null}
      </AnimatePresence>
    </Wrapper>
  );
}

export default App;

AnimatePresence 사용

  • AnimatePresence의 내부에서 나타나거나 사라지는 게 있다면 애니메이션 효과를 적용할 수 있도록 해준다.
  • exit: 현재 element가 사라질 때 어떤 애니메이션을 발생시킬지 정할 수 있다.

 

1-1) 애니메이션 효과가 끝나면 함수 실행 방법

<AnimatePresence initial={false} onExitComplete={함수}>
  • onExitComplete: exit가 끝났을 때 실행하고 싶은 함수를 넣는다.
  • initial={false} : false를 주면 최초 렌더링 시 애니메이션 효과를 실행하지 않는다.

 

 


2. AnimatePresence 사용한 슬라이드 구현 방법

interface IBack {
  isBack: boolean;
}

const box = {
  // return 함수로 변경
  entry: ({ isBack }: IBack) => ({
    // return하고 싶으면 괄호로 둘러 싸야한다.
    // x 500 오른쪽에서 나타난다.
    x: isBack ? -500 : 500,
    opacity: 0,
    scale: 0,
  }),
  center: {
    x: 0,
    opacity: 1,
    scale: 1,
    transition: {
      duration: 0.5,
    },
  },
  exit: ({ isBack }: IBack) => ({
    // x -500 왼쪽으로 사라진다.
    x: isBack ? 500 : -500,
    opacity: 0,
    scale: 0,
    transition: {
      duration: 0.5,
    },
  }),
};

function App() {
  const [visible, setVisible] = useState(1);
  const [isBack, setIsBack] = useState(false);
  const nextPlease = () => {
    setIsBack(false);
    setVisible((prev) => (prev === 10 ? 10 : prev + 1));
  };
  const prevPlease = () => {
    setIsBack(true);
    setVisible((prev) => (prev === 1 ? 1 : prev - 1));
  };
  return (
    <Wrapper>
      {/* custom에 Object로 넣어 준다. */}
      <AnimatePresence custom={{ isBack }}>
        <Box
          custom={{ isBack }}
          variants={box}
          initial="entry"
          animate="center"
          exit="exit"
          key={visible}
        >
          {visible}
        </Box>
      </AnimatePresence>
      <button onClick={nextPlease}>next</button>
      <button onClick={prevPlease}>prev</button>
    </Wrapper>
  );
}

export default App;
  • element는 key를 변경하는 것만으로 element가 사라졌다고 생각한다.
    element가 사라졌다고 생각하면 exit animate가 실행되고. 다시 key를 변경하면 컴포넌트를 re-render 해준다.
  • custom에 값을 넘겨준다.
custom 사용방법 (custom은 variant에 데이터를 보낼 수 있게 해주는 property이다.)
1. variant Object를 return 함수로 바꿔야 한다. (위의 box 변수 참조)
2. AnimatePresence 컴포넌트와 슬라이드 컴포넌트 둘 다 custom값을 줘야 한다.
3. custom 값은 Obejct Type으로 넘겨주어야 한다. (Obejct로 넘기지 않으면 슬라이드 효과가 이상해질 경우가 있다.)

AnimatePresence 슬라이드 구현

 

 

2-1) 애니메이션 효과 중복 방지

<AnimatePresence custom={{ isBack }} mode="wait">
	...
</AnimatePresence>
  • mode="wait"을 주면 하나의 애니메이션 효과가 끝나고 다음 효과가 실행된다.

 

 

반응형