일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
- height속성
- 자식결합자
- iframe 태그
- padding 속성
- 아두이노
- focus 의사클래스
- html 태그
- iframe
- 인접 형제 결합자
- sup태그
- 전체 선택자
- RGB
- Live Server
- sub태그
- not 의사클래스
- reveal in file explorer
- go live
- tag html
- Checked 의사 클래스
- background-color 속성
- width속성
- id 선택자
- RGBA
- i 태그
- br 태그
- 임베디드
- css
- 일반 형제 결합자
- html
- html tag i
- Today
- Total
so woon!
[FRAMER MOTION] useMotionValue + useTransform 사용하기 본문
학습일 : 2023. 05. 13
useMotionValue 는
애니메이션 내의 수치를 트래킹(추적)하고자 할 때 사용할 수 있다.
예를 들면
아래 코드에서는 motion.div의 x좌표를 추적하고 있다.
import{ motion, useMotionValue } from "framer-motion"
export function MyComponent() {
const x = useMotionValue(0)
return <motion.div style={{ x }} />
}
유저가 왼쪽으로 드래깅하는지, 오른쪽으로 드래깅하는지의 여부를 알고 싶을 때
사용할 수 있을 것이다.
값을 추적하기 위해서는 useMotionValue를 import 해주어야 하고
style={{ x }}를 써줘서 useMotionValue와 style의 x를 연결해주도록 한다.
<App.tsx>
style의 x좌표가 바뀔 때마다 MotionValue 역시 업데이트 됨
function App() {
const x = useMotionValue(0);
return (
<Wrapper>
<Box style={{ x }} drag="x" dragSnapToOrigin></Box>
</Wrapper>
);
}
export default App;
참고로 MotionValue가 바뀌어도 컴포넌트는 다시 렌더링 되지 않는다.
변하는 x의 값을 확인해보기 위해
useEffect를 사용하여 확인해보도록 한다.
<App.tsx>
import { styled } from "styled-components";
import { motion, useMotionValue } from "framer-motion";
import { useEffect } from "react";
// style
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
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.06);
`;
function App() {
const x = useMotionValue(0);
// useEffect 사용으로 x값 추적하기
// x값이 바뀔때마다 x값이 콘솔에 찍혀나옴.
useEffect(() => {
x.on("change", () => console.log(x.get()));
}, [x]);
return (
<Wrapper>
<Box style={{ x }} drag="x" dragSnapToOrigin></Box>
</Wrapper>
);
}
export default App;
실행결과
이번엔 버튼을 하나 만들어서
그 버튼을 클릭했을 때 x 위치를 바꿀수도 있음
<App.tsx>
button에 onClick={()=> x.set(200)} 을 적어줌
import { styled } from "styled-components";
import { motion, useMotionValue } from "framer-motion";
import { useEffect } from "react";
// style
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
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.06);
`;
function App() {
const x = useMotionValue(0);
return (
<Wrapper>
<button onClick={() => x.set(200)}>click me</button>
<Box style={{ x }} drag="x" dragSnapToOrigin></Box>
</Wrapper>
);
}
export default App;
실행결과
useTransform 사용하기
1. 박스를 드래그하는 위치에 따라 크기 변경하기
이번에는 사각형을 드래그해서 왼쪽 끝을 향하여 갈때
사각형을 점점 커지게
오른쪽 끝을 향해 갈때는 작아지게 해보고자 한다.
-800일 때 : scale이 2가 되도록 하고,
0일 때 : scale이 1이 되도록 하고,
800일 때 : scale이 0이 되도록
만들어 주면 되는데
useTransform에는 값을 3개 적어주어야 한다.
1. 값 : x
2. 검토하길 원하는 입력값 (x가 ___일 때 라는 의미) : 배열 [-800, 0, 800]
3. 얻길 원하는 출력값 : 배열을 적어줌 [2, 1, 0.1]
* 입력값의 갯수는 출력값의 갯수와 같아야함. *
function App() {
const x = useMotionValue(0); // x값은 드래그할 때마다 새로 값이 설정됨
const scaleValue = useTransform(x, [-800, 0, 800], [2, 1, 0.1]);
// useEffect 대신 useMotionValueEvent 사용
useMotionValueEvent(scaleValue, "change", (el) => console.log(el));
return (
<Wrapper>
<button onClick={() => x.set(200)}>click me</button>
<Box style={{ x }} drag="x" dragSnapToOrigin></Box>
</Wrapper>
);
}
export default App;
실행결과
그리고 콘솔에 출력되어지는 값을 보면 -800이 되었을 때 2라는 값이 나오고
중간일 때에는 1,
800이 되었을 때에는 0.1에 가까운 숫자가 찍혀나오는 걸 볼 수 있다.
React Native에서는
const scale = useTransform(x, [-800, 0, 800], [2, 1, 0.1]);
이 코드를 interpolation이라고 부른다.
useMotionValueEvent는 이제 필요 없으니 지워주도록 하고
이제 이것을 state와 연결시켜주면 된다.
import { styled } from "styled-components";
import { motion, useMotionValue, useMotionValueEvent, useTransform } from "framer-motion";
// style
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
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.06);
`;
function App() {
const x = useMotionValue(0);
const scaleValue = useTransform(x, [-800, 0, 800], [2, 1, 0.1]);
return (
<Wrapper>
<Box style={{ x, scale:scaleValue }} drag="x" dragSnapToOrigin></Box>
</Wrapper>
);
}
export default App;
실행결과
2. 드래그 하는 위치에 따라 박스 회전하기
박스를 회전을 시켜보고자 하면 Box 컴포넌트 안 style에 rotate를 작성해주면 된다.
그리고 useTransform에 회전을 어떻게 시켜줄지 아래와 같이 적어주면 된다
import { styled } from "styled-components";
import { motion, useMotionValue, useTransform } from "framer-motion";
// style
const Wrapper = styled.div`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
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.06);
`;
function App() {
const x = useMotionValue(0);
const rotateValue = useTransform(x, [-800, 800], [-360, 360]);
return (
<Wrapper>
<Box style={{ x, rotateZ:rotateValue }} drag="x" dragSnapToOrigin></Box>
</Wrapper>
);
}
export default App;
실행결과
3. 박스를 드래그 하는 위치에 따라 배경색 바꿔보기
역시 같은 방식으로 작성해주고
배경이 될 Wrapper 컴포넌트에 style로 적용해주면 된다.
import { styled } from "styled-components";
import { motion, useMotionValue, useTransform } from "framer-motion";
// style
const Wrapper = styled(motion.div)`
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
`;
// 박스
const Box = styled(motion.div)`
width: 200px;
height: 200px;
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.06);
`;
function App() {
const x = useMotionValue(0);
const rotateZ = useTransform(x, [-800, 800], [-360, 360]);
const gradient = useTransform(
x,
[-800, 800],
[
"linear-gradient(135deg, rgb(0, 210, 238), rgb(22, 103, 135))",
"linear-gradient(135deg, rgb(52, 178, 145), rgb(212, 212, 107))",
]
);
return (
<Wrapper style={{ background: gradient }}>
<Box style={{ x, rotateZ: rotateZ }} drag="x" dragSnapToOrigin></Box>
</Wrapper>
);
}
export default App;
실행결과
'Framer Motion > 개념정리' 카테고리의 다른 글
[FRAMER MOTION] svg Animation (0) | 2023.05.14 |
---|---|
[FRAMER MOTION] useScroll (0) | 2023.05.14 |
[FRAMER MOTION] Drag Constraint (드래그 제약) (0) | 2023.05.12 |
[FRAMER MOTION] Dragging (0) | 2023.05.11 |
[FRAMER MOTION] Gestures (0) | 2023.05.11 |