[jQuery - 실습] Making a Scroll Trigger

테크야끼·2021년 5월 15일
1

jQuery

목록 보기
9/11

💡 Scroll trigger

원페이지 웹사이트를 만들다 보면 스크롤이 내렸을 때 진행되는 애니메이션을 구현해야 할 때가 있다. 애니메이션을 특별한 조건없이 걸게되면 페이지가 로드되는 순간 애니메이션이 진행되기 때문에 유저가 스크롤을 내려 해당 섹션을 보는 시점은 이미 애니메이션이 끝나있는 상태가 되어버린다.

유저가 특정섹션에 스크롤하는 순간 애니메이션을 진행시키기 위해서는 스크롤 트리거로 만들고 일정한 조건을 주어 조건을 만족시킬 때만 애니메이션을 진행시켜야 한다.

특정 시점에서 간단한 애니메이션을 걸어주는 것은 wow.js 같은 플러그인을 이용해 구현할 수 있지만 현재 작업중인 웹사이트에서 비교적 복잡한 애니메이션을 스크롤 트리거로 만들고 있기 때문에 jQuery의 메서드를 이용해 스크롤 트리거를 만들어 보았다.

counter animation


스크롤 트리거를 적용시킬 섹션에는 0에서부터 지정해준 숫자까지 숫자가 올라가는 애니메이션을 만들어 두었다.

counter animation은 지난번 포스팅에 자세하게 설명해두었다!
counter animation 만들러가기!

HTML

    <div class="situation__icon">
      <img src="./imgs/banner-icon1.png" alt="banner icon">
      <h1 class="countNum">1699595</h1>
      <h3>Confirmed<br>Deaths</h3>
    </div>
    <div class="situation__icon">
      <img src="./imgs/banner-icon2.png" alt="banner icon">
      <h1 class="countNum">106138</h1>
      <h3>Confirmed<br>Deaths</h3>
    </div>
    <div class="situation__icon">
      <img src="./imgs/banner-icon3.png" alt="banner icon">
      <h1 class="countNum">750235</h1>
      <h3>Confirmed<br>Recovered</h3>
    </div>
   

HTML에는 h1 태그에 숫자를 넣고 countNum 이라는 클래스를 주었다.

💡 로직구현

만들고 싶은 스크롤 트리거의 조건은 다음과 같다.

  1. 스크롤 트리거는 스크롤의 높이가 변화하는 것에 따라 동작한다.

  2. 특정섹션에 스크롤이 애니메이션이 오면 작동한다.

  3. 애니메이션은 페이지가 로드된 이후 한 번만 작동한다.

스크롤 트리거의 핵심은 스크롤이 어디에 위치하고있에 있는데 이것을 제어하기 위해서는 3가지의 개념을 이해해야한다.

  • JavaScsript

    Window.innerHeight

    윈도우의 가로 스크롤 막대의 높이 (있는 경우)를 포함하여 윈도우 내부 높이를 픽셀 단위로 반환한다.

    .scrollTop()

    요소의 콘텐츠가 세로로 스크롤되는 픽셀 수를 가져 오거나 설정한다.
    요소의 scrollTop 값은 요소의 상단에서 최상위 표시 콘텐츠까지의 거리를 측정 한 것이다.
    요소의 콘텐츠가 수직 스크롤바를 생성하지 않으면 해당 scrollTop 값은 0이다.

  • jQuery

    .offset()

    선택한 요소 집합의 첫 번째 요소의 위치를 HTML 문서를 기준으로 반환하거나, 선택한 요소의 위치를 인수로 전달받은 값으로 설정한다.
    요소의 상대적인 위치값을 알 수 있으며, top과 left값을 반환한다.

JavaScript

실제로 작성한 코드는 아래와 같다.

$(function () {
  // 1. 한 번만 작동시키기 위한 변수 선언
  let a = 0;
  
  //2. scroll값이 변화할때 발생할 이벤트 호출
  $(window).scroll(function () {
   
    //3. 요소의 top 값 - 윈도우 내부 높이
    let oTop = $('.countNum').offset().top - window.innerHeight;
    
    console.log(`elem offsetTop : ${$('.countNum').offset().top}`);
    console.log(`window heihgt : ${window.innerHeight}`);

    console.log(oTop);

      //4. 3에서 받은 값(oTop)을 세로 스크롤 값과 비교
      // oTop이 스크롤값이 넘을 경우 애니메이션 실행 
    if (a == 0 && $(window).scrollTop() > oTop) {
      $('.countNum').each(function () {
        $(this)
          .prop('Counter', 0)
          .animate(
            {
              Counter: $(this).text(),
            },
            {
              duration: 3000,
              easing: 'swing',
              step: function (now) {
                $(this).text(Math.ceil(now));
                a = 1;
              },
            }
          );
      });
    }
  });
});

1. 한 번만 작동시키기 위한 변수 선언

임의의 변수 a = 0; 를 주어 애니메이션이 끝난 뒤 변수값을 변경하여 a = 1; 애니메이션이 한 번만 실행되게 한다.

2. scroll값이 변화할때 발생할 이벤트 호출

스크롤을 변경했을 때 이벤트를 호출하여 애니메이션이 진행되게 한다.

3. 요소의 top 값 - 윈도우 내부 높이

이 부분은 윈도우 화면 높이를 계산해야하는 코드이기 때문에 이해하기 쉽게 그림으로 그려보았다.

하늘색 안이 우리가 보는 윈도우 화면의 100vh 100vw 이다

let oTop = $('.countNum').offset().top -window.innerHeight;

offset().top은 선택한 요소의 높이값을 픽셀단위로 반환한다. 쉽게 설명하자면 CSS에서 요소에 position : absolute를 주고 top 값을 2000을 준다고 생각하면 된다. 그림 속 요소는 윈도우창 가장 위부터 2000px 만큼 떨어져있으며 거리값도 당연히 2000이다. (비율에 맞게 그리면 더 이해하기 쉬우나 그러면 너무 많은 공간을 차지해서 윈도우 화면에서 벗어난 높이는 작게 그렸다)

window.innerHeight는 우리가 보고있는 윈도우창의 높이를 말하며 개발창을 열었을 때 확인할 수 있는 화면높이이기도 하다.

예를든 그림에서 $('요소').offset().top -window.innerHeight;를 하면

2000 - 500 = 1500
oTop 은 1500이 된다.

oTop은 값은 무엇이냐?

윈도우가 제어할 요소까지 스크롤 되었을 때 윈도우 최상위에서 스크롤이 떨어진 부분까지의 높이를 계산한 것이 된다.

최종적으로 oTop의 값이 애니메이션을 진행시키기 위한 조건이 된다.

실제로 내가 만든 페이지에 코드를 넣어 콘솔창을 찍어보면 결과는 아래와 같다. 이 페이지에서는 스크롤이 3621.078125 높이에 오는 순간 애니메이션이 작동된다.

if (a == 0 && $(window).scrollTop() > oTop)

이렇게 받아온 oTop값을 토대로 조건문을 만든다. oTop은 조건이기 때문에 실시간으로 받아올 스크롤의 높이$(window).scrollTop() 와 비교한다.

위의 그림에서 노란화살표로 표시한 부분이 된다. 그림의 상태는 요소가 보이는 부분까지 스크롤이 내려져있지만 페이지가 로드되고 스크롤이 최상위에 있을 때 (0) 부터 스크롤을 내리면서 그 값은 점점 증가되어 1500에 오는 순간 조건이 만족되고 애니메이션이 작동된다!

💡 완성

[참고]
https://developer.mozilla.org/enUS/docs/Web/API/Window/innerHeight
https://developer.mozilla.org/enUS/docs/Web/API/Element/scrollTop

1개의 댓글

comment-user-thumbnail
2021년 8월 9일

안녕하세요. 스크롤 시 카운팅되는 숫자 코드를 짜기 위해 검색하다하다가 여기 포스트까지 찾아오게 되었는데요, 따라해볼려고하는데 몇가지 여쭤봐도 괜찮을까요? 혹시 initial.min.css 이건 reset 파일인건지.. 그리고 common.js 파일이 있는데.. 이 파일이 생소해서 찾아보니 ['.js' 파일 간의 어떻게 의존성을 가지게 할지 정해주는 것]라던데.. 사용하시는 common.js 파일 코드 여쭤봐도될까요..

답글 달기