일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- RGBA
- id 선택자
- go live
- sub태그
- html 태그
- sup태그
- height속성
- background-color 속성
- i 태그
- tag html
- width속성
- 전체 선택자
- padding 속성
- RGB
- Live Server
- 인접 형제 결합자
- focus 의사클래스
- Checked 의사 클래스
- css
- 아두이노
- iframe
- html
- html tag i
- reveal in file explorer
- iframe 태그
- br 태그
- not 의사클래스
- 일반 형제 결합자
- 임베디드
- 자식결합자
- Today
- Total
so woon!
[FRAMER MOTION] layout, layoutId 사용하기 본문
학습일 : 2023. 05. 16
layout 사용하기
element에 layout prop을 주게 되면
element의 layout이 바뀔 때
알아서 animate가 된다.
만약 css 때문에 layout이 바뀐다면
알아서 animation이 만들어질 것이다.
<Box
style={{
justifyContent: clicked ? "center" : "flex-start",
alignItems: clicked ? "center" : "flex-start",
}}
>
위 코드대로라면 center부터 flex-start까지의 animation 말이다.
Circle component에 layout 을 써보도록 하겠다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useState } from "react";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
background: linear-gradient(135deg, rgb(252, 191, 248), rgb(21, 151, 203));
`;
const Box = styled(motion.div)`
width: 400px;
height: 400px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
display: flex;
`;
const Circle = styled(motion.div)`
background-color: #00a5ff;
width: 100px;
height: 100px;
border-radius: 50px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
`;
function App() {
const [clicked, setClicked] = useState(false);
const toggleClicked = () => setClicked((prev) => !prev);
return (
<Wrapper onClick={toggleClicked}>
<Box
style={{
justifyContent: clicked ? "center" : "flex-start",
alignItems: clicked ? "center" : "flex-start",
}}
>
<Circle layout />
</Box>
</Wrapper>
);
}
export default App;
실행결과
Framer Motion은 무언가 외부의 힘에 의해 바뀐 것을 감지한다.
뭔가를 간단하게 animate 해주고 싶으면
layout을 써주면 될 것으로 보인다.
layoutId 사용하기
(shared layout animation)
첫번째 박스안 원이 클릭을 안했을 때 원이 나타나고
클릭을 했을 때 원이 사라지게
그리고 그걸 계속 반복할 수 있게 한다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useState } from "react";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
background: linear-gradient(135deg, rgb(252, 191, 248), rgb(21, 151, 203));
`;
const Box = styled(motion.div)`
width: 300px;
height: 300px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
`;
const Circle = styled(motion.div)`
background-color: #00a5ff;
width: 50px;
height: 50px;
border-radius: 50px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
`;
function App() {
const [clicked, setClicked] = useState(false);
const toggleClicked = () => setClicked((prev) => !prev);
return (
<Wrapper onClick={toggleClicked}>
<Box>
{!clicked ? <Circle /> : null}
</Box>
<Box>
<Circle />
</Box>
</Wrapper>
);
}
export default App;
실행결과
나머지 박스안 원에도 적용해본다 (반대로)
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useState } from "react";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
background: linear-gradient(135deg, rgb(252, 191, 248), rgb(21, 151, 203));
`;
const Box = styled(motion.div)`
width: 300px;
height: 300px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
`;
const Circle = styled(motion.div)`
background-color: #00a5ff;
width: 50px;
height: 50px;
border-radius: 50px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
`;
function App() {
const [clicked, setClicked] = useState(false);
const toggleClicked = () => setClicked((prev) => !prev);
return (
<Wrapper onClick={toggleClicked}>
<Box>
{!clicked ? <Circle /> : null}
</Box>
<Box>
{clicked ? <Circle /> : null}
</Box>
</Wrapper>
);
}
export default App;
실행결과
영상3
여기서 왼쪽 박스안 Circle과 오른쪽 박스안 Circle이
같은 component라고 Framer에게 말해주어야 한다.
즉 <Circle /> 두개를 연결해야 한다는 뜻이다.
<Wrapper onClick={toggleClicked}>
<Box>
{!clicked ? <Circle /> : null}
</Box>
<Box>
{clicked ? <Circle /> : null}
</Box>
</Wrapper>
연결하기 위해서는
두 Circle component 안에
layoutId 라는 prop을 추가하면 되고,
두개 다 같은 Id를 작성해주면 된다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useState } from "react";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
background: linear-gradient(135deg, rgb(252, 191, 248), rgb(21, 151, 203));
`;
const Box = styled(motion.div)`
width: 300px;
height: 300px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
`;
const Circle = styled(motion.div)`
background-color: #00a5ff;
width: 50px;
height: 50px;
border-radius: 50px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
`;
function App() {
const [clicked, setClicked] = useState(false);
const toggleClicked = () => setClicked((prev) => !prev);
return (
<Wrapper onClick={toggleClicked}>
<Box>
{!clicked ? <Circle layoutId="circle" /> : null}
</Box>
<Box>
{clicked ? <Circle layoutId="circle" /> : null}
</Box>
</Wrapper>
);
}
export default App;
실행결과
Framer가 둘을 연결해주고 animation을 만들게 된다.
스타일도 바꿔볼 수 있다.
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useState } from "react";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
background: linear-gradient(135deg, rgb(252, 191, 248), rgb(21, 151, 203));
`;
const Box = styled(motion.div)`
width: 300px;
height: 300px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
`;
const Circle = styled(motion.div)`
background-color: #00a5ff;
width: 50px;
height: 50px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
`;
function App() {
const [clicked, setClicked] = useState(false);
const toggleClicked = () => setClicked((prev) => !prev);
return (
<Wrapper onClick={toggleClicked}>
<Box>
{!clicked ? (
<Circle layoutId="circle" style={{ borderRadius: 50 }} />
) : null}
</Box>
<Box>
{clicked ? (
<Circle layoutId="circle" style={{ borderRadius: 0 }} />
) : null}
</Box>
</Wrapper>
);
}
export default App;
실행결과
오른쪽으로 가면 borderRadius가 0으로 바뀌면서
자동으로 animation이 적용됨을 볼 수 있다.
scale도 변화시켜보면
import { styled } from "styled-components";
import { motion } from "framer-motion";
import { useState } from "react";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
background: linear-gradient(135deg, rgb(252, 191, 248), rgb(21, 151, 203));
`;
const Box = styled(motion.div)`
width: 300px;
height: 300px;
background-color: rgba(255, 255, 255, 1);
border-radius: 40px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
align-items: center;
display: flex;
flex-direction: row;
justify-content: center;
`;
const Circle = styled(motion.div)`
background-color: #00a5ff;
width: 50px;
height: 50px;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.1);
`;
function App() {
const [clicked, setClicked] = useState(false);
const toggleClicked = () => setClicked((prev) => !prev);
return (
<Wrapper onClick={toggleClicked}>
<Box>
{!clicked ? (
<Circle layoutId="circle" style={{ borderRadius: 50 }} />
) : null}
</Box>
<Box>
{clicked ? (
<Circle layoutId="circle" style={{ borderRadius: 0, scale:3 }} />
) : null}
</Box>
</Wrapper>
);
}
export default App;
실행결과
'Framer Motion > 개념정리' 카테고리의 다른 글
[FRAMER MOTION] popup (0) | 2023.05.16 |
---|---|
[FRAMER MOTION] AnimatePresence + 슬라이더 만들기 (0) | 2023.05.15 |
[FRAMER MOTION] svg Animation (0) | 2023.05.14 |
[FRAMER MOTION] useScroll (0) | 2023.05.14 |
[FRAMER MOTION] useMotionValue + useTransform 사용하기 (0) | 2023.05.13 |