넷째주 #20 React Js - framer-motion (MotionValue)

김선은·2023년 6월 8일

MotionValue

애니메이션 내의 수치를 트래킹. 방향과 값에 따라 다른 모습을 보여줄 수 있음.
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/


드래그 방향에 따라 scale 변화

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])

useScroll - 스크롤 감지하기

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을 줌. 
//스크롤을 내리면 스크롤의 정도에 따라 박스의 크기가 커진다.
)
profile
기록은 기억이 된다

0개의 댓글