Framer Motion 라이브러리가 제공하는 API중 가장 토대가 된다고 할 수 있는 몇 가지 API를 훑어보겠습니다.
motion />
컴포넌트Framer motion의 근간이 되는것이 바로 motion 컴포넌트입니다. 쉽게 생각해서 애니메이션 능력이 가미된 HTML요소라고 생각하면 좋습니다.
<motion.div />
import "./styles.css";
import { motion } from "framer-motion";
export default function App() {
return (
<motion.div
className="box"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
/>
);
}
앞서 언급한 motion 컴포넌트에 애니메이션을 넣으려면 animate
라는 prop을 전달하면 됩니다.
<motion.div animate={{ x: 100 }}/>
위처럼 전달해준 값들이 바뀌면 Framer motion이 가장 최신 상태의 값을 반영하여 애니메이션을 자동 생성해줍니다. 다음과 같이 transition
prop으로 애니메이션을 정교하게 설정할 수 있습니다.
<motion.div
animate={{ x: 100 }}
transition={{
delay: 1000,
type: "spring",
}}
/>
framer motion에는 아주 강력한 제스쳐 감지 시스템이 있어 hover, tap, pan, drag의 제스쳐 이벤트를 핸들링할 수 있게 해줍니다. <motion />
컴포넌트가 리액트의 이벤트 시스템을 extend하면서 구현되어 있습니다.
<motion.div
whileHover={{ scale: 1.2 }}
whileTap={{ scale: 1.1 }}
drag="x"
dragConstraints={{ left: -100, right: 100 }}
/>
Variants를 사용하여 단 하나의 animate
prop으로 해당 컴포넌트의 전체 서브 트리에 애니메이션을 줄 수 있습니다.
Variants는 애니메이션 prop에 해당하는 미리 정의된 애니메이션 객체 세트라고 보면 됩니다. Variants를 통해 선언적인 방식으로 애니메이션을 적용할 수 있습니다.
const list = { hidden: { opacity: 0 } }
const item = { hidden: { x: -10, opacity: 0 } }
return (
<motion.ul animate="hidden" variants={list}>
<motion.li variants={item} />
<motion.li variants={item} />
<motion.li variants={item} />
</motion.ul>
)
whileInView
prop을 사용하여 컴포넌트가 뷰포트 안쪽으로 진입할 때와 나갈 때를 타겟하여 애니메이션을 줄 수도 있습니다.
<motion.div
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
/>
컴포넌트의 애니메이션이 적용된(animated state) 상태는 서버에서 렌더링됨으로써 마운트시 스타일링이 다시 일어나는것을 방지합니다.
<motion.div
initial={false}
animate={{ x: 100 }}
/>
MotionValues
는 리액트의 렌더링 생애주기 밖에서 애니메이션 값들의 속도나 상태를 tracking하는데에 사용됩니다. 생성은 자동으로 되고, motion 컴포넌트가 내부적으로 사용합니다.
MotionValues
는 수동으로도 생성할 수 있는데요, MotionValues
를 생성함으로써 컴포넌트에 연동시켜 더욱 성능좋은 애니메이션 효과들을 선언적으로 구현할 수 있습니다.
const x = useMotionValue(0)
const opacity = useTransform(x, [-100, 0, 100], [0, 1, 0])
return <motion.div drag="x" style={{ x, opacity }} />
Framer motion으로 레이아웃의 변경에도 애니메이션을 적용할 수 있습니다.
<motion.div layout />
useAnimate
훅으로 사이드이펙트나 이벤트 핸들러 안에서 특정 애니메이션을 수동으로 트리거할 수 있습니다. 또한 useAnimate훅을 사용하여 더욱 복잡한 애니메이션을 지휘할 수도 있습니다.
<div onClick={() => animate(".boxes", { opacity: 0 })} />
npm install framer-motion
또는
yarn add framer-motion
import { motion } from "framer-motion"