GSAP - 숫자 카운터 애니메이션

n-u·2022년 8월 20일
0

GSAP

목록 보기
1/1

⌛ GSAP을 이용한 숫자 카운트 애니메이션 만들기

이번에는 변화되는 숫자가 위에서 아래로, 아래에서 위로 움직여 변화하는 애니메이션 모션을 만들어보았습니다.
랜딩페이지에 숫자가 변화되는 애니메이션을 래퍼런스로하여 GSAP을 이용해 사용해보았습니다.

(디테일적인 면은 완전히 다르지만, 일단은 숫자가 변경되는 모습을 구현하는 것에 초점을 맞췄습니다)
또한, 이 페이지는 odometor.js를 이용한 것 같습니다.

구상

  • 애니메이션 구상은 .number-wrapy(translateY)값을 조절해 화면에 보이는 숫자가 변경되어 보이도록 합니다.
  • 숫자 변화를 동일하게 주기 위해서 숫자 0 - 9li를 한 번 더 만들어 그 numberWrapy값에 변화를 주고자 했습니다.
  • 만들어질 함수에 인자 값이 화면에 나오는 숫자와 동일하도록 만드는 것을 목표로 하였습니다.

HTML

<section id="numberCount">
                <div class="Count-wrap">
                    <ul class="nb1">
                        <span class="number-wrap">
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>

                        </span>
                    </ul>
                    <ul class="nb2">
                        <span class="number-wrap">
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>

                        </span>
                    </ul>
                    <ul class="nb3">
                        <span class="number-wrap">
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>

                        </span>
                    </ul>
                    <ul class="nb4">
                        <span class="number-wrap">
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>
                            <li>0</li>
                            <li>1</li>
                            <li>2</li>
                            <li>3</li>
                            <li>4</li>
                            <li>5</li>
                            <li>6</li>
                            <li>7</li>
                            <li>8</li>
                            <li>9</li>

                        </span>
                    </ul>
                </div>
            </section>

모션을 만들게 되면 불필요한 HTML태그들을 생성해야 한다는 것을 이번 카운터 애니메이션을 만들면서 알게 되었습니다.
이것들을 사용할때만 생성해서 화면 상에 나타낼 수 없을까 하는 생각이 듭니다만, 실력이 부족하다는 것을 알고 있으므로, 제가 할 수 있는 최선의 방법으로 HTML과 CSS를 최대한 이용해 만들어 보았습니다.

CSS

#numberCount{
    display: flex;
    justify-content: center;
    flex-direction : column;
    width: 100%;
    height: 200%;
    margin-top : 50px;
    text-align : center;
/*     border : 3px solid red; */
  }
  #numberCount > .Count-wrap{
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top : 50px;
  }
  #numberCount > .Count-wrap ul{
    position: relative;
    display: block;
    width: 200px;
    height: 100px;
/*     border: 3px solid salmon; */
    overflow: hidden;
  }
  .number-wrap{
    display: block;
  }
  #numberCount li{
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-shrink : 1;
    font-size: 100px;
/*     border: 7px solid yellow; */
  }

JS(GSAP)

const numberWrap = document.querySelector(".number-wrap");
const number = document.querySelector(".number-wrap li");
const numberHeight = number.offsetHeight;

//gsap 애니메이션을 타이밍을 한번에 관리하기 위해 timeline을 사용했습니다.
const counterTimeline = gsap.timeline();

//numberWrap이 이동할때, 루즈하지 않도록 해주기 위해 위치 값을 변화를 크게 주기 위해 지정한 변수 : r
let r = 0;

//이동할 값 계산해주는 함수
const count = (i) => {
  let rv = -(numberHeight * (i + 10 * r));
  return rv;
};

//애니메이션 호출 함수
const countAnimation = (n, m, o, p) => {
  counterTimeline
    .add("start")
    .to(
    ".nb1 .number-wrap",
    { y: count(n), ease: " Power1.easeOut" },
    "start"
  )
    .to(
    ".nb2 .number-wrap",
    { y: count(m), ease: " Power1.easeOut" },
    "start+=0.3"
  )
    .to(
    ".nb3 .number-wrap",
    { y: count(o), ease: " Power1.easeOut" },
    "start+=0.5"
  )
    .to(
    ".nb4 .number-wrap",
    { y: count(p), ease: " Power1.easeOut" },
    "start+=0.7"
  );
	//r의 값의 조건을 걸어 이동값에 변화를 줍니다.
  if (r === 0) {
    r++;
  } else if (r == 1) {
    r--;
  }
};

//초기값
countAnimation(1, 9, 8, 7);

//Gsap을 이용해 해당영역에서 애니메이션이 실행되도록 설정합니다.
ScrollTrigger.create({
  trigger: "#numberCount",
  start: "top-=5% top",
  end: "+=100%",
  scroller: pageContainer,
  pin: true,
  markers: true,
  scrub: true,
  onEnter: () => {
    countAnimation(2, 0, 2, 2);
    //뷰포트와 start값이 위에서 아래로 스크롤할때 함수 실행
  },
  onLeaveBack: () => {
    countAnimation(1, 9, 8, 7);
    //뷰포트와 start값이 아래에서 위로 스크롤될떄 함수 실행
  },
});


⌛ 마치며...

현재 만든 예제에는 HTML코드 상으로 보기가 안좋은 것 같단 생각이 듭니다. 반복되는 것들이 많다고 할까요.. 자바스크립트 코드 같은 경우에는 객체로 묶에 HTML에 넣어주거나, 반복되는 코드를 반복문을 돌려 실행하는 것은 어떨까하는 아쉬움이 있습니다만, 지금의 제 실력은 여기까지 인 것 같습니다.
클래스나 프로토타입를 이용해 코드를 정리하도록 공부해야 할 것 같습니다. ㅎ

profile
기록하며 발전하는 삶

0개의 댓글