본문으로 바로가기

intersection observer

스크롤을 내리다가 특정 element가 보이는 시점에 애니메이션이 동작하는 UI를 보셨을 겁니다.

dom요소의 가시성을 측정하는 intersection observer를 활용하면 됩니다.

 

찾아보니까 이것도 많이 쓰더라구요?

커밋이 1번 뿐인데 직접 구현해도 되긴 합니다.

www.npmjs.com/package/react-intersection-observer

 

react-intersection-observer

Monitor if a component is inside the viewport, using IntersectionObserver API

www.npmjs.com

 

useScrollFadeIn hook

import { useRef, useEffect, useCallback } from 'react';

const useScrollFadeIn = (direction = 'up', duration = 1, delay = 0) => {
  const element = useRef();

  const handleDirection = (name) => {
    switch (name) {
      case 'up':
        return 'translate3d(0, 50%, 0)';
      case 'down':
        return 'translate3d(0, -50%, 0)';
      case 'left':
        return 'translate3d(50%, 0, 0)';
      case 'right':
        return 'translate3d(-50%, 0, 0)';
      default:
        return;
    }
  };

  const onScroll = useCallback(
    ([entry]) => {
      const { current } = element;
      if (entry.isIntersecting) {
        current.style.transitionProperty = 'all';
        current.style.transitionDuration = `${duration}s`;
        current.style.transitionTimingFunction = 'cubic-bezier(0, 0, 0.2, 1)';
        current.style.transitionDelay = `${delay}s`;
        current.style.opacity = 1;
        current.style.transform = 'translate3d(0, 0, 0)';
      }
    },
    [delay, duration],
  );

  useEffect(() => {
    let observer;

    if (element.current) {
      observer = new IntersectionObserver(onScroll, { threshold: 0.7 });
      observer.observe(element.current);
    }

    return () => observer && observer.disconnect();
  }, [onScroll]);

  return {
    ref: element,
    style: { opacity: 0, transform: handleDirection(direction) },
  };
};

export default useScrollFadeIn;

 

이런 식으로 사용하면 되겠다.

<ItemBox {useScrollFadeIn('up', 1, 0)}>
  <div>what</div>
</ItemBox>

 

 

참고)

github.com/jus0k/scroll-hooks

shylog.com/react-custom-hooks-scroll-animation-fadein

 


darren, dev blog
블로그 이미지 DarrenKwonDev 님의 블로그
VISITOR 오늘 / 전체