Framer Motion - 리액트 라이브러리
Framer Motion은 단순하면서도 강력한 React용 모션 라이브러리이다.
1. 설치하기
yarn add framer-motion
npm install framer-motion
2. 기본 사용법
- import { motion } from 'framer-motion'; 으로 motion을 불러옵니다.
- motion이 들어갈 요소에 motion을 붙여줍니다.
- initial(초기값)과 animate(애니메이션)을 설정합니다.
- styled-components를 사용하는 경우에는 styled(motion.div)로 사용합니다.
import { motion } from 'framer-motion';
import styled from 'styled-components';
export default function App() {
const box = {
width: '200px',
height: '200px',
borderRadius: '50%',
background: 'blue',
};
return (
<>
<motion.div style={box} initial={{ opacity: 0 }} animate={{ opacity: 1, x: 100 }} />
<MotionOpacity initial={{ opacity: 0 }} animate={{ opacity: 1, scale: 1.2, y: -100 }} />
</>
);
}
const MotionOpacity = styled(motion.div)`
width: 200px;
height: 200px;
background: red;
`;
3. 옵션 정리
속성 | 설명 |
---|---|
initial | 초기 값 설정 |
animate | 애니메이션 설정 |
Transition | 애니메이션 시간, 이징 등 설정 |
Variants | 애니메이션 유형 설정 |
whileHover | 마우스 호버 시 애니메이션 설정 |
whileTap | 마우스 클릭 시 애니메이션 설정 |
whileFocus | 포커스 시 애니메이션 설정 |
whileDrag | 드래깅 시 애니메이션 설정 |
exit | 요소 사라질 때 애니메이션 설정 |
animatePresence | 요소 사라질 때 애니메이션 설정 |
drag | 드래그 설정 |
dragConstraints | 드래그 범위 설정 |
dragElastic | 드래그 탄성 설정 |
dragMomentum | 드래그 관성 설정 |
dragPropagation | 드래그 전파 설정 |
layout | 레이아웃 설정 |
layoutId | 레이아웃 ID 설정 |
layoutTransition | 레이아웃 애니메이션 설정 |
onHoverStart | 마우스 호버 시작 이벤트 설정 |
onHoverEnd | 마우스 호버 종료 이벤트 설정 |
onTap | 마우스 클릭 이벤트 설정 |
onFocus | 포커스 이벤트 설정 |
onDragStart | 드래깅 시작 이벤트 설정 |
onDragEnd | 드래깅 종료 이벤트 설정 |
onDrag | 드래깅 이벤트 설정 |
onDragTransitionEnd | 드래그 애니메이션 종료 이벤트 설정 |
onLayoutAnimationComplete | 레이아웃 애니메이션 완료 이벤트 설정 |
onPanStart | 팬 시작 이벤트 설정 |
onPanEnd | 팬 종료 이벤트 설정 |
onPan | 팬 이벤트 설정 |
onPanTransitionEnd | 팬 애니메이션 종료 이벤트 설정 |
4. 애니메이션
Simple animations, transitions
- x, y, scale, rotate, opacity, backgroundColor, borderRadius 등의 애니메이션을 사용할 수 있습니다.
https://codesandbox.io/s/framer-motion-enter-animation-forked-3sdxyz?file=/src/App.tsx
<motion.div
initial={{ opacity: 0, x: -100, scale: 0.5 }}
animate={{ opacity: 1, x: 0, scale: 2 }}
transition={{ ease: 'easeOut', duration: 2 }}
/>
Keyframes
- keyframes를 사용하면 애니메이션을 더 세밀하게 조정할 수 있습니다.
https://codesandbox.io/s/framer-motion-keyframes-0fzv21?from-embed
<motion.div
className="box"
animate={{
scale: [1, 2, 2, 1, 1],
rotate: [0, 0, 270, 270, 0],
borderRadius: ['20%', '20%', '50%', '50%', '20%'],
}}
transition={{
duration: 2,
ease: 'easeInOut',
times: [0, 0.2, 0.5, 0.8, 1],
repeat: Infinity,
repeatDelay: 1,
}}
/>
- keyframes의 초기값에 null을 전달하여 현재 값을 초기 키프레임으로 사용할 수 있습니다.
https://codesandbox.io/s/framer-motion-wildcard-keyframes-dkk0xr?from-embed=&file=/src/App.tsx
<motion.div animate={{ x: [null, 100, 0] }} />
Variants
- variants를 사용하여 애니메이션을 변수로 관리할 수 있습니다.
https://codesandbox.io/s/framer-motion-side-menu-mx2rw?from-embed
import { motion } from 'framer-motion';
const variants = {
// 애니메이션 변수
open: { opacity: 1, x: 0 }, // open 상태
closed: { opacity: 0, x: '-100%' }, // closed 상태
};
export const MyComponent = () => {
const [isOpen, setIsOpen] = useState(false); // isOpen 상태 관리
return (
// isOpen 상태에 따라 애니메이션 적용
// isOpen 상태 변경
<motion.nav animate={isOpen ? 'open' : 'closed'} variants={variants}>
<Toggle onClick={() => setIsOpen((isOpen) => !isOpen)} />
<Items />
</motion.nav>
);
};
gestures
Hover
- 마우스 호버 시 애니메이션을 설정할 수 있습니다.
<motion.div whileHover={{ scale: 1.2 }} />
Tap
- 마우스 클릭 시 애니메이션을 설정할 수 있습니다.
<motion.div whileTap={{ scale: 0.8 }} />
Focus
- 포커스 시 애니메이션을 설정할 수 있습니다.
<motion.div whileFocus={{ scale: 1.2 }} />
drag
- 드래그 시 애니메이션을 설정할 수 있습니다.
<motion.div whileDrag={{ scale: 0.8 }} />
주요 예제
1. State, Variants
https://codesandbox.io/s/framer-motion-variants-rj7ks0?from-embed=&file=/src/App.tsx:0-1980
import './styles.css';
import { useState } from 'react';
import { motion, Variants } from 'framer-motion';
const itemVariants: Variants = {
open: {
opacity: 1,
y: 0,
transition: { type: 'spring', stiffness: 300, damping: 24 },
},
closed: { opacity: 0, y: 20, transition: { duration: 0.2 } },
};
export default function App() {
const [isOpen, setIsOpen] = useState(false);
return (
<motion.nav initial={false} animate={isOpen ? 'open' : 'closed'} className="menu">
<motion.button whileTap={{ scale: 0.97 }} onClick={() => setIsOpen(!isOpen)}>
Menu
<motion.div
variants={{
open: { rotate: 180 },
closed: { rotate: 0 },
}}
transition={{ duration: 0.2 }}
style={{ originY: 0.55 }}
>
<svg width="15" height="15" viewBox="0 0 20 20">
<path d="M0 7 L 20 7 L 10 16" />
</svg>
</motion.div>
</motion.button>
<motion.ul
variants={{
open: {
clipPath: 'inset(0% 0% 0% 0% round 10px)',
transition: {
type: 'spring',
bounce: 0,
duration: 0.7,
delayChildren: 0.3,
staggerChildren: 0.05,
},
},
closed: {
clipPath: 'inset(10% 50% 90% 50% round 10px)',
transition: {
type: 'spring',
bounce: 0,
duration: 0.3,
},
},
}}
style={{ pointerEvents: isOpen ? 'auto' : 'none' }}
>
<motion.li variants={itemVariants}>Item 1 </motion.li>
<motion.li variants={itemVariants}>Item 2 </motion.li>
<motion.li variants={itemVariants}>Item 3 </motion.li>
<motion.li variants={itemVariants}>Item 4 </motion.li>
<motion.li variants={itemVariants}>Item 5 </motion.li>
</motion.ul>
</motion.nav>
);
}
'Front > React' 카테고리의 다른 글
React GitHub 배포, Netlify 배포 (0) | 2023.11.13 |
---|---|
React Library (0) | 2023.11.06 |
상태(State) - React 배우기 (0) | 2023.10.31 |
이벤트(Event) - React 배우기 (0) | 2023.10.31 |
속성(Props, Properties) - React 배우기 (0) | 2023.10.29 |