일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- br 태그
- tag html
- 임베디드
- height속성
- Checked 의사 클래스
- background-color 속성
- css
- Live Server
- 인접 형제 결합자
- sup태그
- iframe
- html
- reveal in file explorer
- html 태그
- RGB
- sub태그
- id 선택자
- 전체 선택자
- 일반 형제 결합자
- html tag i
- iframe 태그
- not 의사클래스
- 자식결합자
- padding 속성
- i 태그
- RGBA
- width속성
- focus 의사클래스
- 아두이노
- go live
- Today
- Total
so woon!
[FRAMER MOTION] svg Animation 본문
학습일 : 2023. 05. 14
font awesome 등의 사이트에서
원하는 로고 또는 아이콘을 고르고
svg탭에서 코드를 복사 해서
Wrapper 안에 붙여주고
스타일링을 해준다.
모든 svg는 path를 가지고 있고,
path는 fill을 가지고 있다.
애니메이션 적용을 위해
path에도
그냥 <path />를 쓰면 안되고
<motion.path /> 로 바꾸어 주어야 한다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
const Svg = styled.svg`
width: 300px;
height: 300px;
`;
function App() {
return (
<Wrapper>
<Svg
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<motion.path
//처음상태
initial={{ fill: "rgba(134, 73, 255, 0)" }}
// 최종상태
animate={{
fill: "rgba(134, 73, 255, 1)",
}}
transition={{ duration: 3 }}
stroke="rgb(134, 73, 255)" // stroke를 작성하면 선이 생김
strokeWidth="3" // 선굵기
d="M391.17,103.47H352.54v109.7h38.63ZM285,103H246.37V212.75H285ZM120.83,0,24.31,91.42V420.58H140.14V512l96.53-91.42h77.25L487.69,256V0ZM449.07,237.75l-77.22,73.12H294.61l-67.6,64v-64H140.14V36.58H449.07Z"
/>
</Svg>
</Wrapper>
);
}
export default App;
실행결과
pathLength
pathLength는 현재 위치까지의 path의 길이를 나타낸다.
pathLength 값을 바꿔서 위치를 조정할 수 있음.
일단은 처음 0위치에서 시작해서 1위치에서 끝나도록 해보면
import { styled } from "styled-components";
import { motion } from "framer-motion";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
const Svg = styled.svg`
width: 300px;
height: 300px;
`;
function App() {
return (
<Wrapper>
<Svg
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<motion.path
//처음상태
initial={{ pathLength: 0, fill: "rgba(134, 73, 255, 0)" }}
// 최종상태
animate={{
fill: "rgba(134, 73, 255, 0)",
pathLength: 1,
}}
transition={{ duration: 3 }}
stroke="rgb(134, 73, 255)"
strokeWidth="3"
d="M391.17,103.47H352.54v109.7h38.63ZM285,103H246.37V212.75H285ZM120.83,0,24.31,91.42V420.58H140.14V512l96.53-91.42h77.25L487.69,256V0ZM449.07,237.75l-77.22,73.12H294.61l-67.6,64v-64H140.14V36.58H449.07Z"
/>
</Svg>
</Wrapper>
);
}
export default App;
실행결과
이 상태에서 animate 의 opacity를 1로 변경해주면
import { styled } from "styled-components";
import { motion } from "framer-motion";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
const Svg = styled.svg`
width: 300px;
height: 300px;
`;
function App() {
return (
<Wrapper>
<Svg
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<motion.path
//처음상태
initial={{ pathLength: 0, fill: "rgba(134, 73, 255, 0)" }}
// 최종상태
animate={{
fill: "rgba(134, 73, 255, 1)",
pathLength: 1,
}}
transition={{ duration: 3 }}
stroke="rgb(134, 73, 255)"
strokeWidth="3"
d="M391.17,103.47H352.54v109.7h38.63ZM285,103H246.37V212.75H285ZM120.83,0,24.31,91.42V420.58H140.14V512l96.53-91.42h77.25L487.69,256V0ZM449.07,237.75l-77.22,73.12H294.61l-67.6,64v-64H140.14V36.58H449.07Z"
/>
</Svg>
</Wrapper>
);
}
export default App;
실행결과
그리고 이 모든 애니메이션들을
variants
를 작성하여 묶어주도록 하겠다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
const Svg = styled.svg`
width: 300px;
height: 300px;
// 여기서 path의 stroke, stroke-width를 작성해 주어도 상관없음.
path {
stroke: rgb(134, 73, 255);
stroke-width: 2;
}
`;
// variants
const svg = {
start: { pathLength: 0, fill: "rgba(134, 73, 255, 0)" },
end: {
fill: "rgba(134, 73, 255, 1)",
pathLength: 1,
transition: { duration: 5 },
},
};
function App() {
return (
<Wrapper>
<Svg
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<motion.path
variants={svg}
//처음상태
initial="start"
// 최종상태
animate="end"
d="M391.17,103.47H352.54v109.7h38.63ZM285,103H246.37V212.75H285ZM120.83,0,24.31,91.42V420.58H140.14V512l96.53-91.42h77.25L487.69,256V0ZM449.07,237.75l-77.22,73.12H294.61l-67.6,64v-64H140.14V36.58H449.07Z"
/>
</Svg>
</Wrapper>
);
}
export default App;
실행결과는 아까와 똑같음.
default값을 줘서 모든 트랜지션의 default duration을 설정해주기
<motion.path>안에서도 transition을 줄 수 있는데
transition으로 default: { duration: 5 } 를 주면 이전과 같이
총 5초동안 애니메이션이 일어남.
import { styled } from "styled-components";
import { motion } from "framer-motion";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
const Svg = styled.svg`
width: 300px;
height: 300px;
path {
stroke: rgb(134, 73, 255);
stroke-width: 2;
}
`;
// variants
const svg = {
start: { pathLength: 0, fill: "rgba(134, 73, 255, 0)" },
end: {
fill: "rgba(134, 73, 255, 1)",
pathLength: 1,
},
};
function App() {
return (
<Wrapper>
<Svg
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<motion.path
variants={svg}
//처음상태
initial="start"
// 최종상태
animate="end"
// transition - default값 (모든 트랜지션의 default duration을 5로 설정)
transition={{
default: { duration: 5 },
}}
d="M391.17,103.47H352.54v109.7h38.63ZM285,103H246.37V212.75H285ZM120.83,0,24.31,91.42V420.58H140.14V512l96.53-91.42h77.25L487.69,256V0ZM449.07,237.75l-77.22,73.12H294.61l-67.6,64v-64H140.14V36.58H449.07Z"
/>
</Svg>
</Wrapper>
);
}
export default App;
실행결과
이전과 같음.
특정 property 트랜지션만 따로 변경해주기
위에 적어준 것처럼 <motion.path> 안에서 transition으로
default를 작성하여
모든 트랜지션의 default duration을 설정해줄 수 있지만,
특정 property의 트랜지션을 따로 변경해주고 싶다면
예를 들어 fill의 트랜지션을 따로 변경하고 싶으면
transition 안에 fill을 적어주고 변경할 값들을 적어주면 된다.
아래와 같이 작성해주면 된다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
const Svg = styled.svg`
width: 300px;
height: 300px;
path {
stroke: rgb(134, 73, 255);
stroke-width: 2;
}
`;
// variants
const svg = {
start: { pathLength: 0, fill: "rgba(134, 73, 255, 0)" },
end: {
fill: "rgba(134, 73, 255, 1)",
pathLength: 1,
},
};
function App() {
return (
<Wrapper>
<Svg
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 512 512"
>
<motion.path
variants={svg}
//처음상태
initial="start"
// 최종상태
animate="end"
// property의 transition 시간 정하기
transition={{
default: { duration: 5 },
fill: { duration: 2, delay: 4 }, // fill만 duration을 2, delay를 4로 설정
}}
d="M391.17,103.47H352.54v109.7h38.63ZM285,103H246.37V212.75H285ZM120.83,0,24.31,91.42V420.58H140.14V512l96.53-91.42h77.25L487.69,256V0ZM449.07,237.75l-77.22,73.12H294.61l-67.6,64v-64H140.14V36.58H449.07Z"
/>
</Svg>
</Wrapper>
);
}
export default App;
실행결과
4초 후에 fill animation이 나오게 됨.
'Framer Motion > 개념정리' 카테고리의 다른 글
[FRAMER MOTION] layout, layoutId 사용하기 (0) | 2023.05.16 |
---|---|
[FRAMER MOTION] AnimatePresence + 슬라이더 만들기 (0) | 2023.05.15 |
[FRAMER MOTION] useScroll (0) | 2023.05.14 |
[FRAMER MOTION] useMotionValue + useTransform 사용하기 (0) | 2023.05.13 |
[FRAMER MOTION] Drag Constraint (드래그 제약) (0) | 2023.05.12 |