React

[React] Framer Motion(2) 드래그(Drag) 추적 값(useMotionValue) 사용 방법

cob 2022. 9. 30. 12:55
라이브러리 설치 및 기본 사용 법은 아래 링크에서 확인
https://cocococo.tistory.com/29

 

 

1. Drag 효과 

const boxVariants = {
  hover: { scale: 1.5, rotateZ: 90 },
  click: { scale: 1, borderRadius: "100px" },
  
  // 색상을 줄때 string형(blue 등)으로 주면 animate가 안된다. rgb값을 넣어야 한다. 
  drag: { backgroundColor: "rgb(46,204,113)", transition: { duration: 3 } },
};

function App() {
  return (
    <Wrapper>
      <Box
        drag
	dragSnapToOrigin
        variants={boxVariants}
        whileHover="hover"
        whileTap="click"
        whileDrag="drag"
      />
    </Wrapper>
  );
}
export default App;
  • whileHover : 마우스를 올려놓았을 때
  • whileTap : 마우스로 클릭 했을 때
  • drag : 드래그 기능 활성화(컴포넌트 이동 o)
  • dragSnapToOrigin : 드래그 후 다시 중앙으로 되돌아온다
  • whileDrag : 드래그하는 동안 컴포넌트를 변경

 

1-1) Drag 제약

<Box
    drag="x"
    variants={boxVariants}
    whileHover="hover"
    whileTap="click"
/>
  • drag="x" : x 축 좌표 내에서만 드래그 가능( y = y 축 좌표)

 

 

1-2) dragConstraints를 사용한 드래그 영역 제한

const boxVariants = {
  hover: { scale: 1.5, rotateZ: 90 },
  click: { scale: 1, borderRadius: "100px" },
};
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);
`;
const BiggerBox = styled.div`
  width: 600px;
  height: 600px;
  border-radius: 40px;
  background-color: rgba(255, 255, 255, 0.4);
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: hidden; // 영역 밖에 나가면 숨김
`;

function App() {
  const biggerBoxRef = useRef<HTMLDivElement>(null);
  return (
    <Wrapper>
      <BiggerBox ref={biggerBoxRef}>
        <Box
          drag
          dragConstraints={biggerBoxRef}
          variants={boxVariants}
          whileHover="hover"
          whileTap="click"
        />
      </BiggerBox>
    </Wrapper>
  );
}
  • dragConstraints : 제약이 있는 박스를 만들 수 있다. 드래깅이 허용될 수 있는 영역
  • ref : 특정 element를 접근할 수 있는 방법이다.(드래그 영역 시 필수)
    - 레퍼런스를 만들고(useRef), 이 레퍼런스를 컴포넌트(biggerBox)에 넣는다.
    그 후에 실제 드래그 대상인 컴포넌트(Box)에 제약(dragConstraints)으로 걸어준다.
    (biggerBox의 가장자리까지 드래그 가능하다고 설정)

 

 

 


2. useMotionValue Hook

애니메이션 내의 수치를 트래킹 할 때 필요. 수치를 트래킹 하여 값에 따른 애니메이션 적용한다.
/* 공식 문서 */
https://www.framer.com/docs/motionvalue/##userviewportscroll

 

 

2-1) useMotionValue를 사용한 Drag 값 트래킹 방법

import { motion, useMotionValue } from "framer-motion";
import { useEffect } from "react";
import styled from "styled-components";

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 motionX = useMotionValue(0);
  useEffect(() => {
    // 변경될 때 실행
    motionX.onChange(() => console.log(motionX.get()));
  }, [motionX]);
  return (
    <Wrapper>
      <!-- x좌표를 트래핑 값으로 설정한다 -->
      <Box style={{ x: motionX }} drag="x" dragSnapToOrigin />
	  <button onClick={() => motionX.set(200)}>click</button>
    </Wrapper>
  );
}

export default App;
  • MotionValue가 업데이트될 때에 렌더링을 하지 않는다. 즉, ReactJS State(상태)가 아니다
  • 렌더링 되지 않기 때문에 변경된 값을 보기 위해서는 useEffect를 사용한다.
  • useMotionValue : 특정 값을 추적할 수 있다.
  • style={{ x: motionX }} : 해당 스타일을 적용하게 되면 x좌표 추적된다.
  • x.set(200) : 해당 x축 좌표로 이동

 

 

2-2) useTransform Hook을 사용한 트래킹 값 변경

useMotionValue로 트래킹 값을 useTransform 통해 값을 변경한다.
import { motion, useMotionValue, useTransform } from "framer-motion";

function App() {
  const motionX = useMotionValue(0);
  const scale= useTransform(motionX, [-800, 800], [2, 0.1]);

  return (
    <Wrapper>
      <Box style={{ x: motionX, scale: scale}} drag="x" dragSnapToOrigin />
    </Wrapper>
  );
}
  • 첫 번째 param : 설정 값(트래킹 값)
  • 두 번째 param : 검토를 원하는 값이 담긴 배열(드래그 가능 영역)
  • 세 번째 param : 검토 값 대신  출력 값이 담긴 배열 검토 값의 개수 배열의 개수와 같아야 한다.
    - 자동으로 검토 값의 범위에 맞게 출력 값이 설정된다.
  • useTransform로 변경시킨 값을 scale로 줌으로써 드래그할 때 애니메이션 효과를 준다.

dag 트래핑 활용

 

반응형