[ReactJS_MasterClass] #8 ANIMATIONS (1)

유은선·2023년 2월 25일
0

ReactJS_MasterClass

목록 보기
10/11
post-thumbnail

✍8.0 Introduction

이번 섹션에서는 ReactJs용 라이브러리인Framer Motion을 사용해서 애니메이션을 만드는 방법을 배워보자.
📎https://www.framer.com/motion/

✍8.1 Installation

npm install framer-motion

animate를 하기 원한다면 motion 패키지로부터 나와야한다. 일반 div로는 사용할 수 없고, motion.div로 사용할 수 있다.

✍8.2 Basic Animations

저번 챕터에서 배웠듯이, 무언가를 애니메이트 할 때 motion으로부터 HTML element를 불러와야만 했다.

스타일 컴포넌트를 애니메이트 시킬 수 있는 방법은 다음과 같다.

const Box = styled(motion.div)``;
<Box transition={{ duration: 3 }} animate={{ borderRadius: "100px" }} />

애니메이션을 시작하는 방식을 명시하려면 initial이라는 이름의 prop을 사용하면 된다.

✍8.3 Variants part One

variants는 코드를 깔끔하게 해주고, 많은 애니메이션들을 하나로 연결시켜주는 역할을 한다.

const myVars = {
  start: { scale: 0 },
  end: { scale: 1, rotateZ: 360, transition: { type: "spring", delay: 0.5 } },
};

<Box variants={myVars} initial="start" animate="end" />

variants={myVars}를 써주고, initial에는 myVars 오브젝트 내의 property 이름을 적어주면 된다.

여기서 오브젝트와 프로퍼티 이름은 마음대로 써주면 된다!

✍8.4 Variants part Two

부모인 Box에만 variants를 준 상황에서, 부모 컴포넌트가 variants와 initial, animate의 variant 이름을 갖고 있을 때 motion은 이것들을 복사해서 자동으로 자식들에게 붙여준다.

위, 아래 두개의 코드는 똑같이 동작한다.

<Box variants={boxVariants} initial="start" animate="end">
	<Circle />
	<Circle />
	<Circle />
	<Circle />
</Box>
      
<Box variants={boxVariants} initial="start" animate="end">
	<Circle initial="start" animate="end"/>
	<Circle initial="start" animate="end"/>
	<Circle initial="start" animate="end"/>
	<Circle initial="start" animate="end"/>
</Box> 

위의 코드처럼 Motion은 자식들 각각에 복사 붙여넣기 해주기 때문에 circleVariants는 boxVariants의 이름들을 똑같이 써주면 된다.
부모의 initial 값과 animate 값을 상속한다고 생각하면 된다!

✨부모 variants 내에서 원한다면 delayChildren을 사용하여 모든 자식들에게 delay를 줄 수 있다.
staggerChildren을 사용하면 쉽게 구현할 수 있는데,첫번째 원에 0.5초 delay를 줄 것이고 1초, 1.5초, 2초 순으로 자동적으로 delay를 주게 된다.

✍8.5 Gestures part One

 <Box
        whileHover={{ scale: 1.5, rotateZ: 90 }}
        whileTap={{ scale: 1, borderRadius: "100px" }} />

whileHover, whileTap 안에 오브젝트를 넣는 것 대신에 두 Variants를 만들어 넣어어보자.

const boxVariants = {
  hover: { scale: 1.5, rotateZ: 90 },
  click: { scale: 1, borderRadius: "100px" },
};

<Box variants={boxVariants} whileHover="hover" whileTap="click" />

drag 만 써주면, 바로 드래그 할 수 있다💫

✅ whileDrag에 backgroundColor를 넣으려고 하는데 예를들어 string인 "blue"를 넣어도 즉각적으로 동작하지만 애니메이트하기 어려우므로 rgba 또는 rgb를 이용해서 값을 넣어주면 된다.

✍8.6 Gestures part Two

드래그 제약(contraints) 에 대해 알아보자.
drag="x"라고 작성하면 x선 좌표 내에서만 드래그할 수 있다.

dragConstraints는 기본적으로 제약이 있고 드래깅이 허용될 수 있는 영역인 Box를 만들 수 있다.

중앙 박스가 바깥쪽 박스에 의해 제약이 되게 만드는 법을 배워보자.

✅ 1. 직접 수 계산을 해서 영역 제한하기

<Box
          drag
          dragConstraints={{ top: -200, bottom: 200, left: -200, right: 200 }} />

✅ 2. ref 이용하기 👍

const biggerBoxRef = useRef<HTMLDivElement>(null);
<BiggerBox ref={biggerBoxRef}>
        <Box drag dragConstraints={biggerBoxRef} />

✨Box가 중앙으로 되돌아가게 하려면 dragSnapToOrigin을 쓰기만 하면 된다!

dragElastic은 기본적으로 당기는 힘이 있고, 0에서 1사이의 수로 표현해주면 되는데 기본값은 0.5이다.

✍8.7 MotionValues part One

애니메이션 내의 수치를 트래킹할 때 필요한 MotionValue를 배워보자.

function App() {
  const x = useMotionValue(0);
  console.log(x);
  return (
    <Wrapper>
      <Box style={{ x: x }} drag="x" dragSnapToOrigin />
    </Wrapper>
  );
}

{x:x}를 shortcut으로 {x}로 작성해도 된다.

console.log 코드가 있지만 Box를 움직여도 콘솔에 한번만 출력이 된다. MotionValue가 업데이트 될 때 React Rendering Cycle(렌더링 싸이클)을 발생시키지 않기 때문이다. 즉, MotionValue가 ReactJs State 가 아니라는 것.
따라서 MotionValue가 바뀌어도 내 컴포넌트가 재렌더링되지 않는다.

useEffect(() => {
    x.onChange(() => console.log(x.get()));
  }, [x]);

MotionValue가 업데이트 되었다고 하는데, onChange를 쓰는 대신 useMotionValueEvent를 사용해서 코드를 작성하면 된다.

✍8.8 MotionValues part Two

useTransform을 이용해서 x값을 transforming 해보자.

✍8.9 MotionValues part Three

useScroll 은 MotionValue이다. 즉 state가 아니며 재렌더링을 발동시키지 않는 것을 의미한다.
(최신버전에서는 useViewportScroll ➡ useScroll로 이름 변경됨)

scrollY는 픽셀 단위, scrollYProgress는 0과 1사이의 값으로 스크롤 간격을 알려준다.

profile
뭐든지 난 열심히 하지

0개의 댓글