애니메이션 내의 수치를 트래킹. 방향과 값에 따라 다른 모습을 보여줄 수 있음.
MotionValue는 React State가 아니기 때문에 Motion Value값이 바뀌어도 리랜더링이 일어나지 않는다.
const x = useMotionValue(0);
<Box style={{ x : x }} />
//축약 표현으로 <Box style={{ x }} />
//useMotionValue의 x와 컴포넌트 내의 style x 좌표를 연결.
style의 x 좌표가 바뀔 때, MotionValue 값도 업데이트 된다.
x.set() : useMotionValue 훅을 사용하여 생성한 x 변수의 값 바꾸기
<button onClick={() => x.set(200)}>button</button>
<Box style={{ x }} drag="x" dragSnapToOrigin />
//버튼을 누르면 Box가 우측으로 200 만큼 이동
x.get() : get 메소드로 값을 읽을 수 있다.
https://www.framer.com/docs/motionvalue/
useTransform: 한 값 범위에서 다른 값 범위로 매핑할 수 있음.
MotionValue의 값을 가져다가 다른 MotionValue 만듬.
ex)-800 -400 0 400 800->[-1, -0.5, 0 , 0.5, 1]
useTransform로 만든 값을 style에 연결시켜준다
const x = useMotionValue(0);
const scaleTransform =
useTransform(x, [-800, 0, 800], [2, 1, 0.1]);
// x축 드래그 한 위치에 따라 크기 변화 매핑
// x가 -800일 때, 0일 때, x가 800일 때 ~ output을 2, 1, 0.1로 바꾸겠다.
return (
<Box style={{ x, scale: scaleTransform }}
drag="x" dragSnapToOrigin />
)
//drag 방향 x축으로, 드래그 후 원래 자리로
배경색 지정한 컴포넌트를 모션 컴포넌트로 변경한다
dragSnapToOrigin: 드래그 후 원래 자리로 돌리기
const Wrap = styled(motion.div)``
const Box = styled(motion.div)`
margin: 30px;
width: 200px;
height: 200px;
background-color: rgba(255, 255, 255, 1); // 1이 0.1로 갈수록 투명해짐
border-radius: 20%;
box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1), 0 10px 20px rgba(0, 0, 0, 0.06);
`;
function Animation() {
const x = useMotionValue(0);
const scaleTransform = useTransform(x, [-800, 0, 800], [2, 1, 0.1]);
// 드래그 시 크기 변화
const rotateTransform = useTransform(x, [-800, 800], [-360, 360]);
// 드래그 시 회전
const gradient = useTransform(
x,
[-800, 800],
//["linear-gradient(135deg, #509, #59e)", "linear-gradient(135deg, #808, #d9e)"]
[
"linear-gradient(135deg, rgb(0,210,238), rgb(0,83,245))",
"linear-gradient(135deg, rgb(0,238,155), rgb(238,175,23))",
]
); // 드래그 시 색상 변화
useMotionValueEvent(x, "change", (x) => {
console.log(x);
}); // x 값의 수치 변화를 트래킹
return (
<Wrap style={{ background: gradient }}> //useTransform으로 만든걸 넣음
<Wrapper>
<Box style={{ x, rotateZ: rotateTransform }} drag="x" dragSnapToOrigin />
</Wrapper>
</Wrap>
);
}
https://www.framer.com/motion/use-motion-value-event/
useMotionValueEvent
const {scrollY} = useScroll();
useMotionValueEvent(scrollY, "change", (x) => {
console.log(x);
});
useEffect
const {scrollY} = useScroll();
useEffect(() => {
scrollY.on("change", () => console.log(scrollY.get()))
}, [scrollY])
scrollY: 스크롤 px 값
scrollYProgress: 0과 1 사이 값
const { scrollYProgress } = useScroll();
//scrollYProgress의 값은 0부터 1사이의 값.
const scale = useTransform(scrollYProgress,
[0, 1], [1, 5]);
// useTransform를 이용해서 scrollYProgress의 0 ~ 1 스크롤 값을
// 1 ~ 5 사이의 값으로 매핑
return (
...
<Box style={{ scale }} />
...
//Box의 style에 scale : scale을 줌.
//스크롤을 내리면 스크롤의 정도에 따라 박스의 크기가 커진다.
)