react 스크롤 animation(IntersectionObserver)

이경준·2021년 2월 24일
1


react로 IntersectionObserver를 사용하여 object가 화면 지정한 위치에 도착했을때 애니메이션이 작동되는것을 구현해 보았다.

1. object뿌리기

//App.jsx
const array=[
  {id:1,content:'a'},
  {id:2,content:'b'},
  {id:3,content:'c'},
]

const App = () => {
  return (
    <Styled.Container>
      {array.map((arr, index) => {
        return (
          <Tag
            arrayContent={arr.content}
          />
        );
      })}
    </Styled.Container>
  );
};
//Tag.jsx
const Tag = ({ arrayContent }) => {
  return (
    <div>
      <Styled.Ptag>
        {arrContent}
      </Styled.Ptag>
    </div>
  );
};

먼저 array의 content를 화면에 뿌렸으며 한페이지에 1개의 content가 보이도록 style을 주었다.
(현재는 스크롤 할때마다 'a' => 'b'순으로 넘어간다.)

2. intersectionObserver 적용하기

//Tag.jsx
const Tag = ({ arrContent }) => {
  
  const element = useCallback((node) => {
    const observer = new IntersectionObserver(
      (entries, observer) => {
        console.log(entries
      },
      {
        threshold: 1,
        rootMargin: "0px 0px -20px 0px",
      }
    );

    observer.observe(node);
  }, []);

  return (
    <div>
      <Styled.Ptag
        ref={element}
      >
        {arrContent}
      </Styled.Ptag>
    </div>
  );
};

1.new IntersectionObserver를 사용하여 entries를 console로 확인한다.
2.observer의 option(threshold,rootMargin)을 넣어서 위치를 지정한다.
3.observer.observe(node)를 하여 ref를 관찰한다.
4.tag의 ref를 useCallback의 변수명으로 지정한다.

3. 에니메이션 넣기

//App.jsx
const App = () => {
  const [currentIndex, setCurrentIndex] = useState(-1);

  return (
    <Styled.Container>
      {array.map((arr, index) => {
        return (
          <Tags
            arrContent={arr.content}
            setCurrentIndex={setCurrentIndex}
            index={index}
            isShow={index === currentIndex ? true : false}
          />
        );
      })}
    </Styled.Container>
  );
};
//Tag.jsx
const Tag = ({ arrContent, isShow, setCurrentIndex, index }) => {
  const element = useCallback((node) => {
    const observer = new IntersectionObserver(
      (entries, observer) => {
        setCurrentIndex(index);
      },
      {
        threshold: 1,
        rootMargin: "0px 0px -20px 0px",
      }
    );

    observer.observe(node);
  }, []);

  return (
    <div>
      <Styled.Ptag
        isShow={isShow}
        ref={element}
        style={{ transform: isShow && "scale(5)" }}
      >
        {arrContent}
      </Styled.Ptag>
    </div>
  );
};

1.object가 원하는 위치에 다달했을때 setCurrentIndex(index)하여 state에 index를 넣는다.
2.state가 변하기 때문에 리렌더링된다.
3.App.jsx에서 index와 currentIndex 를 비교하여 같으면 true다르면 false를 보낸다.
4.isShow가 true일경우 scale이 커지게 style을 적용한다.

profile
내가 기억하기위한 블로그

0개의 댓글