Framer 간단한 소개
Framer는 팀이 제품 경험의 모든 부분을 디자인하는 데 도움이 되는 올인원 도구입니다.
프론트개발자 관점에서 Framer의 motion API는 정말 짱입니다.! 👍👍
너무 쉽게 모션, 애니메이션을 컨트롤할수 있습니다. 그리고 무엇 보다 React.JS 기반입니다.!!
Variants 예제코드
Variants은 컴포넌트가 가질 수 있는 미리 정의된 시각적 state입니다.
const variants = {
visible: { opacity: 1 },
hidden: { opacity: 0 },
}
변형 소품을 통해 모션 구성 요소로 전달됩니다.
<motion.div variants={variants} />
이러한 변형은 애니메이션 객체를 정의할 수 있는 모든 위치에서 Props로 참조할 수 있습니다.
<motion.div
initial="hidden"
animate="visible"
variants={variants}
/>
응용코드
import styled from "styled-components";
import { motion } from "framer-motion";
import { useRef } from "react";
const boxVariants = {
start: {
opacity: 0,
scale: 0.5,
},
end: {
scale: 1,
opacity: 1,
transition: {
type: "spring",
duration: 0.5,
bounce: 0.5,
delayChildren: 0.5,
staggerChildren: 0.2,
},
},
};
const circleVariants = {
start: {
opacity: 0,
y: 10,
},
end: {
opacity: 1,
y: 0,
},
};
function App() {
return (
<Wrapper>
<Box variants={boxVariants} initial="start" animate="end">
<Circle variants={circleVariants} />
<Circle variants={circleVariants} />
<Circle variants={circleVariants} />
<Circle variants={circleVariants} />
</Box>
</Wrapper>
);
}
const Box = styled(motion.div)`
width: 200px;
height: 200px;
display: grid;
grid-template-columns: repeat(2, 1fr);
background-color: rgba(255, 255, 255, 0.2);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
const Circle = styled(motion.div)`
width: 70px;
height: 70px;
place-self: center;
border-radius: 35px;
background-color: ${(props) => props.theme.colors.white};
box-shadow: 0 2px 3px rgba(0, 0, 0, 0, 1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
export default App;
응용코드 Gestures
useRef에서 엘리먼트를 가져와서 값을 dragConstraints에 Props로 전달합니다!
여기서 dragSnapToOrigin 옵션은 원점으로 돌릴지, 중앙으로 돌릴지 boolean값으로 설정할수 있습니다!
import styled from "styled-components";
import { motion } from "framer-motion";
import { useRef } from "react";
const boxVariants = {
hover: { scale: 1.5, rotateZ: 90 },
clicl: { scale: 1, borderRadius: "100px" },
drag: { backgroundColor: "rgb(46, 204, 113)", transition: { duration: 1 } },
};
function App() {
const biggerBoxRef = useRef<HTMLDivElement>(null);
return (
<Wrapper>
<BiggerBox ref={biggerBoxRef}>
<Box
drag
dragSnapToOrigin
dragElastic={0.5}
dragConstraints={biggerBoxRef}
variants={boxVariants}
whileHover="hover"
whileDrag="drag"
whileTap="clicl"
/>
</BiggerBox>
</Wrapper>
);
}
const Wrapper = styled.div`
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: ${(props) => props.theme.colors.bgColor};
`;
const BiggerBox = styled.div`
width: 600px;
height: 600px;
background-color: rgba(255, 255, 255, 0.2);
border-radius: 40px;
display: flex;
justify-content: center;
align-items: center;
`;
const Box = styled(motion.div)`
width: 200px;
height: 200px;
background-color: ${(props) => props.theme.colors.white};
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
export default App;