Side Project · 기업

바이비 클론코딩

Vibey 회사 소개 사이트를 혼자 반응형으로 만들며 GSAP 타임라인으로 섹션별 애니메이션을 정리했습니다.

Overview

한눈에 보기

Role
퍼블리싱 전체 (약 3주)
Stack
  • 클론코딩
  • 반응형
  • 애니메이션
  • GSAP
  • jQuery
  • Swiper
Contribution
100%

Description

작업 설명

작업 기간 약 3주, 반응형 웹, 기여도 100%입니다. HTML, CSS, JavaScript와 jQuery, Swiper, Slick, GSAP, Odometer를 사용했습니다.

Key points

문제를 어떻게
풀었는지입니다.

  1. GSAP 애니메이션 타임라인 활용

    Problem섹션마다 애니메이션 동작이 달라 코드가 길어지고 읽기 어려웠습니다.

    Solution영역별 애니메이션을 타임라인 변수로 묶어 순서와 지연 시간을 한곳에서 관리하도록 정리했습니다.

    비주얼 HTML
    <div class="visual_inner w1530">
      <div>
        <h2 class="v_tit">
          <span>VIETNAM NO.1</span>
          <span>BEAUTY</span>
          <span class="line_wrap">PLATFORM
            <span class="line"><em></em></span>
          </span>
        </h2>
        <p class="v_txt">
          <span class="line2"><em></em></span>
          <span class="start one">가장 쉽고 빠르게</span>
          <span class="two">베트남 브랜드 마케팅부터 현지 인플루언서 매칭까지</span>
          <strong class="three">커머스 활동에 필요한 올인원 솔루션</strong>
        </p>
      </div>
    </div>
    인트로 타임라인
    const introAniTl = gsap.timeline({});
    
    introAniTl
      .set('.v_tit span', { yPercent: -60, opacity: 0 }) // 초기값
      .to('.v_tit span:nth-child(1)', { yPercent: 0, opacity: 1, delay: 0.6 })
      .to('.v_tit span:nth-child(2)', { yPercent: 0, opacity: 1, delay: 0.2 })
      .to('.v_tit span:nth-child(3)', { yPercent: 0, opacity: 1 })
      .fromTo('.line', { width: 0, opacity: 0 }, { width: '205%', opacity: 1, duration: 0.4 });
    
    introAniTl
      .from('.v_txt > *', { opacity: 0, y: 60, stagger: 0.3, duration: 0.9 })
      .to('.v_txt .one', { yPercent: 0, opacity: 1, delay: '-= 0.4' })
      .to('.v_txt .two', { yPercent: 0, opacity: 1 })
      .to('.v_txt .three', { yPercent: 0, opacity: 1 });
  2. 애니메이션의 자연스러운 재실행

    Problem스크롤로 영역을 벗어났다가 다시 들어왔을 때 애니메이션이 자연스럽게 다시 재생되지 않았습니다.

    SolutionScrollTrigger의 toggleActions를 "play none none restart"로 두고, 진입·이탈 시점에 active 클래스와 재생·일시정지를 함께 제어했습니다.

    ScrollTrigger 재실행
    const resultAniTl = gsap.timeline({
      scrollTrigger: {
        trigger: '.sc-result',
        start: '0% 0%',
        end: '100% 100%',
        toggleActions: 'play none none restart',
        onEnter: function () {
          $('.sc-result').addClass('active');
          resultAniTl.play(); // 애니메이션을 다시 재생
        },
        onLeaveBack: function () {
          $('.sc-result').removeClass('active');
          resultAniTl.pause();
        },
      },
    });
  3. 제자리에서 숫자가 올라가는 카운터

    ProblemGSAP 카운터를 쓰니 숫자 너비가 바뀌면서 단위 텍스트(건)가 흔들려 산만했습니다.

    Solution계기판형 카운터 라이브러리 Odometer로 바꿔 숫자가 제자리에서 올라가게 하고, GSAP로 영역에 들어올 때 active 클래스를 붙여 실행했습니다.

    카운터 HTML
    <li class="result_item one">
      <dl>
        <dd>
          <h4 class="box_tit">누적 다운로드 수 <em>(2022년 기준)</em></h4>
          <p><strong class="num odometer" id="odometer1" data-download=""></strong>건</p>
        </dd>
        <dt>
          <img src="https://www.vibey.co.kr/img/icons02.svg" alt=""><span class="blind">누적 다운로드 수</span>
        </dt>
      </dl>
    </li>
    진입 시 카운터 실행
    $(window).scroll(function () {
      if ($('.sc-result').hasClass('active')) {
        setTimeout(function () { odometer1.innerHTML = 1500748; }, 2000);
        setTimeout(function () { odometer2.innerHTML = 86; }, 3000);
        setTimeout(function () { odometer3.innerHTML = 172; }, 2000);
      } else { // 초기값
        setTimeout(function () { odometer1.innerHTML = 0; }, 2000);
        setTimeout(function () { odometer2.innerHTML = 19; }, 3000);
        setTimeout(function () { odometer3.innerHTML = 0; }, 2000);
      }
    });

More

다른 작업도 보세요

전체 작업 목록