본문 바로가기

CSS/motion

[motion] React에서 useScroll 훅으로 스크롤 애니메이션 구현하기

Framer Motion의 useScroll 훅은 스크롤 이벤트를 감지하고 이를 통해 애니메이션을 구현하거나 UI를 동적으로 변경하는 데 사용됩니다. 이 훅은 스크롤 위치에 대한 정보를 제공하며, 이를 통해 다양한 애니메이션 효과를 쉽게 구현할 수 있습니다.

useScroll의 용도 및 기능

  • 스크롤 위치 추적: useScroll은 현재 스크롤 위치를 추적하여 이를 기반으로 애니메이션을 적용할 수 있습니다.
  • 모션 값 반환: 이 훅은 scrollX, scrollY, scrollXProgress, scrollYProgress라는 네 가지 모션 값을 반환합니다.
    • scrollXscrollY: 픽셀 단위로 현재 스크롤 위치를 나타냅니다.
    • scrollXProgressscrollYProgress: 0에서 1 사이의 값을 가지며, 스크롤이 시작 지점에서 끝 지점으로 이동할 때의 진행 상황을 나타냅니다.

주요 용도

  1. 스크롤 연동 애니메이션: 스크롤 위치에 따라 요소의 크기, 위치, 색상 등을 변경할 수 있습니다. 예를 들어, 스크롤이 진행될 때 요소의 크기를 점점 키우거나 줄이는 효과를 만들 수 있습니다.
  2. 스크롤 트리거 애니메이션: 특정 요소가 뷰포트에 들어오거나 나갈 때 애니메이션을 트리거할 수 있습니다.

옵션

  • container: 스크롤을 추적할 컨테이너를 지정합니다. 기본적으로 브라우저 창을 추적하지만, 특정 요소의 참조를 전달하여 해당 요소의 스크롤을 추적할 수 있습니다.
  • target: 스크롤 진행 상황을 추적할 요소를 지정합니다. 기본적으로 컨테이너의 스크롤 영역을 추적하지만, 다른 요소의 참조를 전달하여 해당 요소의 진행 상황을 추적할 수 있습니다.
  • axis: 스크롤 축을 지정합니다. 기본적으로 수직 축("y")을 사용합니다.
  • offset
    Default: 
    ["start start", "end end"]
    오프셋은 교차점, 즉 대상과 컨테이너가 만나는 지점을 나타냅니다. 예를 들어 교차점 "start end"는 추적 축에서 target시작과 container의 끝이 만나는 지점을 의미합니다. 따라서 target이 요소이고 container가 창이며 세로 축을 추적하는 경우  "start end" 는 요소의 위쪽과 뷰포트의 아래쪽이 만나는 지점이 됩니다.

오프셋 정의 방법

  • Number: 0에서 1 사이의 값을 사용하여 시작 지점에서 끝 지점까지의 비율을 정의할 수 있습니다.
  • Names: "start", "center", "end"를 사용하여 시작, 중간, 끝 지점을 간편하게 정의할 수 있습니다.
  • Pixels: "100px"와 같은 픽셀 단위로 지정할 수 있습니다.
  • Percent: "0%"에서 "100%"까지의 퍼센트로 지정할 수 있습니다.
  • Viewport: "vh""vw"를 사용하여 뷰포트의 높이와 너비를 기준으로 지정할 수 있습니다.

예시 코드

import { motion, useScroll } from "framer-motion";

function Component() {
  const { scrollYProgress } = useScroll();

  return (
    <motion.div style={{ scaleX: scrollYProgress }} />
  );
}

이 예시에서는 useScroll을 사용하여 스크롤 진행 상황을 추적하고, 이를 기반으로 요소의 크기를 조절합니다.

import { motion, useScroll } from "framer-motion";
import { useRef } from "react";

function Carousel() {
  const carouselRef = useRef(null);
  const { scrollX } = useScroll({ container: carouselRef });

  return (
    <div ref={carouselRef} style={{ overflow: "scroll" }}>
      {/* Carousel items */}
    </div>
  );
}

이 예시에서는 특정 요소의 스크롤을 추적하여 해당 요소 내의 아이템을 애니메이션 효과를 적용할 수 있습니다.