ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • JavaScript로 Scroll Reveal Animation 구현하기
    JavaScript 2024. 4. 29. 16:17

    Next.js 로 프로젝트 중 토스 홈페이지를 보고 스크롤 이벤트 시 요소들이 여러 방향으로 나타나는 애니메이션을 프로젝트 소개 페이지(Intro Page)에 적용하고 싶었습니다. 그래서 React로 만들기에 앞서 JavaScript로 구현하여 원리를 파악하려 합니다. 다음 자료를 참고하여 구현해 보았습니다. 

    ✅  구현하고 싶은 내용

    Scroll Reveal Animation를 적용하고 싶은 요소가 viewport에 들어왔을 때 애니메이션이 실행되게 하려고 합니다.

    ✅  transition, transform, animation

    • transition
      • transition: property duration timing-function delay;
      • transition은 hover나 onClick과 같은 이벤트 트리거에 의해 동작합니다.
      • 예시
    div { 
        width: 100px; 
        height: 50px; 
        background-color: red; 
        margin-bottom: 10px; 
        transition-property: width, 
        background-color; /* 어떤 css 프로퍼티(width)를 transition할지 지정 */ 
        transition-duration: 2s, 2s; /* width와 bg-color가 2초동안 변화 */ 
    }
    
    div:hover { /* 마우스를 올리면 transition발동해서 적용될 상태 */
        width: 300px;
        background-color: blue;
    }
    • transform
      • transform : scale(x,y) translate(x,y) rotate(deg) skew(xdeg,ydeg);
    • CSS animation
      • 애니메이션을 사용하면 트랜지션보다 화려한 css를 구현할 수 있습니다.
      • 트랜지션은 시작하기 위해 이벤트가 필요하지만 애니메이션은 시작, 정지, 반복까지 제어할 수 있습니다.
      • animation : @keyframes의 이름 animation-delay animation-duration animation-timing-function
        • animation-name: 키프레임 이름 (필수)
        • animation-iteration-count: 애니메이션 반복 횟수, infinite를 적어주면 무한반복 됩니다.
        • animation-direction: 애니메이션 방향으로 normal, reverse, alternate, alternate-reverse가 있습니다.
          • normal: 정방향
          • reverse: 역방향
          • alternate: 정방향 ➡️ 역방향 ➡️ 정방향 ... (alternate는 반복이 2이상 일 때부터 확인할 수 있습니다.)
          • alternate-reverse: 역방향 ➡️ 정방향 ➡️ 역방향...
        • animation-fill-mode: 애니메이션이 재생되지 않을 때 (애니메이션 시작 전(대기), 끝난 후(종료)) element의 스타일을 지정합니다.
          • none: 애니메이션 실행 전후 요소에 스타일 반영 x (애니메이션 종료 후 속성 값을 되돌림)
          • forwards: 마지막 키 프레임에서 설정한 스타일 값을 유지
          • backwards: 첫 번째 키 프레임(애니메이션 방향에 따라 다릅니다.)에 의해 설정된 스타일 값을 가져오고 애니메이션 지연 기간 동안 이를 유지
          • both: forwards, backwards를 모두 따름
    @keyframes [키프레임 이름] {
      0%   {background-color:red; left:0px; top:0px;}
      25%  {background-color:yellow; left:200px; top:0px;}
      50%  {background-color:blue; left:200px; top:200px;}
      75%  {background-color:green; left:0px; top:200px;}
      100% {background-color:red; left:0px; top:0px;}
    }

     

    ✅  getBoundingClientRect(), window.innerHeight() ,clientHeight() 을 이용하여 구현하기

     

    el.getBoundingClientRect().top() 값과 document.document.clientHeight() (= 뷰포트 높이 값) 값을 이용해서 스크롤시 element가 나타나고 사라지는 순간을 포착하고, element가 viewport에 노출되는 순간 스타일(".js-scroll")을 추가해 애니메이션이 시작하게 하고, 끝나면 제거하는 방법으로 구현했습니다. IE8 이하 버전에서는 window.innerHeight가 지원되지 않기 때문에 window.innerHeight()를 이용한 조건도 함께 달아줄 수 있습니다.

     

     

    const scrollElements = document.querySelectorAll('.js-scroll')
    
    const elementInView = (el, dividend = 1) => {
      const elementTop = el.getBoundingClientRect().top
    
      // viewport 기준 element top이 보이기 시작할때는 감지한다.
      return (
        elementTop <=
        (window.innerHeight || document.documentElement.clientHeight / dividend) // dividend // 4/5 배
      )
    }
    
    // el가 viewport 아래로 사라질때를 감지한다.
    const elementOutofView = (el) => {
      const elementTop = el.getBoundingClientRect().top
    
      return (
        elementTop > window.innerHeight || document.documentElement.clientHeight
      )
    }
    
    const displayScrollElement = (el) => {
      el.classList.add('scrolled')
    }
    
    const hideScrollElement = (el) => {
      el.classList.remove('scrolled')
    }
    
    const handleScrollAnimation = () => {
      scrollElements.forEach((el) => {
        if (elementInView(el, 1.25)) {
          displayScrollElement(el)
        } else if (elementOutofView(el)) {
          hideScrollElement(el)
        }
      })
    }
    
    window.addEventListener('scroll', () => {
      handleScrollAnimation()
    })

     

     

    ✅  결과물

     

     

    다음 게시물에서는 React로 구현해보고 애니메이션 실행 방향을 props으로 받아서 component로 만들어 보려고 합니다.

     

     

    React로 Scroll Reveal Animation 구현하고 컴포넌트화 하기

    <figure id="og_1714447333650" contenteditable="false" data-ke-type="opengraph" data-ke-align="alignCenter" data-og-type="article" data-og-title="JavaScript로 Scroll Reveal Animation 구현하기" data-og-description="Next.js 로 프로젝트 중 토스

    dev-ea-jung.tistory.com

     

    반응형

    댓글

Designed by Tistory.