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"을 주면 하나의 애니메이션 효과가 끝나고 다음 효과가 실행된다.

 

 

반응형