Front/Library

GSAP을 이용한 Parallax Scrolling

oodada 2024. 5. 29. 14:52

GSAP을 이용한 Parallax Scrolling

패럴랙스 스크롤링은 웹사이트의 요소들이 서로 다른 속도로 움직이는 것

  • 레이어별 스크롤 속도를 다르게 하여 입체감을 주는 디자인 기법
  • 게임, 애니메이션 등에서 주로 사용되던 기법으로 인터랙티브한 웹사이트를 만들 때 사용
  • javascript, css, 라이브러리 등을 이용하여 구현

Parallax Scrolling

GSAP이란?

웹 페이지나 웹 앱에서 다양한 애니메이션 효과를 만들 수 있도록 도와주는 강력한 도구로 널리 사용됩니다.

  • GSAP
  • 이 라이브러리는 웹 개발자들에게 다양한 기능과 API를 제공하여 스무스하고 반응적인 웹 애니메이션을 쉽게 구현할 수 있게 해줍니다.
  • GSAP (GreenSock Animation Platform)은 HTML5 기반의 애니메이션 라이브러리로, CSS, SVG, Canvas, WebGL 등 다양한 요소에 애니메이션을 적용할 수 있습니다.
  • ScrollTrigger는 GSAP의 플러그인으로, 스크롤에 따라 요소에 애니메이션을 적용할 수 있습니다.
  • GSAP 코드펜 : GSAP의 다양한 예제를 확인할 수 있습니다.

GSAP, ScrollTrigger 설치하기

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.4/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.4/ScrollTrigger.min.js"></script>
  • NPM
npm install gsap
npm install gsap@3.6.0
npm install gsap@3.6.0 scrolltrigger

GSAP 사용법

gsap.to('요소', { 옵션, 시간 })

  • GSAP docs

  • 요소에 애니메이션을 적용

  • gsap.to() : 현재 상태에서 시작하여 지정된 상태로 애니메이션을 적용

  • gsap.from() : 지정된 상태에서 시작하여 현재 상태로 애니메이션을 적용

  • gsap.fromTo() : 지정된 상태에서 시작하여 지정된 상태로 애니메이션을 적용

gsap.to(".box1", {
        x: 400,
        y: 400,
        rotation: 45,
        backgroundColor: "blue",
        duration: 2,
      });

Timeline 사용법

gsap.timeline()

  • Timeline docs

  • 여러 개의 애니메이션을 순차적으로 실행

  • add() : 해당 요소에 애니메이션을 추가

  • addLabel() : 해당 요소에 레이블을 추가

  • play() : 애니메이션을 실행

  • pause() : 애니메이션을 일시정지

  • reverse() : 애니메이션을 역방향으로 실행

  • time() : 애니메이션의 시간을 설정

  • seek() : 애니메이션의 위치를 설정

  • duration() : 애니메이션의 지속 시간을 설정

  • repeat() : 애니메이션을 반복

  • yoyo() : 애니메이션을 왕복

  • progress() : 애니메이션의 진행 상태를 설정

  • kill() : 애니메이션을 중지

const tl = gsap.timeline();

tl.to(".box2", { y: 200, duration: 2 })
  .to(".box2", { x: 200, duration: 2 })
  .to(".box2", { rotation: 45, scale: 2 })
  .to(".box2", { backgroundColor: "red", duration: 2 });

ScrollTrigger 사용법

  • ScrollTrigger docs

  • 스크롤에 따라 요소에 애니메이션을 적용

  • trigger : 트리거가 되는 요소

  • start : 트리거가 되는 요소의 시작 위치

  • end : 트리거가 되는 요소의 끝 위치

  • scrub : 스크롤 속도에 따라 애니메이션 속도가 달라짐

  • pin : 해당 요소를 고정

  • markers : 해당 요소의 트리거를 표시

gsap.registerPlugin(ScrollTrigger);

gsap.to(".box1", {
  x: 400,
  y: 400,
  backgroundColor: "blue",
  duration: 2,
  scrollTrigger: {
    trigger: ".section1", // 객체 기준 범위
    start: "0 30%", // 시작 위치
    end: "100% 60%", // 끝 위치
    scrub: true, // 스크롤 속도에 따라 애니메이션 속도 조절
    // markers: true, // 개발 가이드선
  },
});

const tl = gsap.timeline({
  scrollTrigger: {
    trigger: ".section2", // 객체 기준 범위
    start: "0 0", // 시작 위치
    end: "+=400", // 끝 위치
    scrub: 0.7, // 스크롤 속도에 따라 애니메이션 속도 조절
    markers: true, // 개발 가이드선
    pin: true,
  },
});

tl.to(".box2", {
  y: 200,
  duration: 2,
})
  .to(".box2", {
  x: 200,
  duration: 2,
})
  .to(".box2", {
  rotation: 45,
  scale: 2,
});

Parallax Scrolling을 이용한 Header, topButton 애니메이션

- 200px 이상 스크롤 시, Header 숨기기

/**
 * 페이지 스크롤에 따른 요소 제어
 */
// 페이지 스크롤에 영향을 받는 요소들을 검색!
const headerEl = document.querySelector('#header');
const toTopEl = document.querySelector('#to-top');
// 페이지에 스크롤 이벤트를 추가!
// 스크롤이 지나치게 자주 발생하는 것을 조절(throttle, 일부러 부하를 줌)
window.addEventListener(
    'scroll',
    _.throttle(function () {
        // 페이지 스크롤 위치가 200px 이상.
        if (window.scrollY > 200) {
            // Badge 요소 숨기기!
            // gsap.to(요소, 시간, 옵션);
            gsap.to(headerEl, {
                opacity: 0,
                display: 'none',
                duration: 0.6,
            });
            // 상단으로 스크롤 버튼 보이기!
            gsap.to(toTopEl, {
                right: '30px',
                // x: 0,
                duration: 0.2,
            });

            // 페이지 스크롤 위치가 500px이 넘지 않으면.
        } else {
            // 스크롤이 200px 이하일 경우
            // Badge 요소 보이기!
            gsap.to(headerEl, {
                opacity: 1,
                display: 'block',
                duration: 0.6,
            });
            // 상단으로 스크롤 버튼 숨기기!
            gsap.to(toTopEl, {
                right: '-50px',
                // x: 100,
                duration: 0.2,
            });
        }
    }, 300),
);
// 상단으로 스크롤 버튼을 클릭하면,
toTopEl.addEventListener('click', function () {
    // 페이지 위치를 최상단으로 부드럽게(0.7초 동안) 이동.
    gsap.to(window, {
        scrollTo: 0,
        duration: 0.7,
    });
});

/**
 * 순서대로 나타나는 기능
 */
// 나타날 요소들(.fade-in) 찾기.
const fadeEls = document.querySelectorAll('.visual .fade-in');
// 나타날 요소들을 하나씩 반복해서 처리!
fadeEls.forEach(function (fadeEl, index) {
    // 각 요소들을 순서대로(delay) 보여지게 함!
    gsap.to(fadeEl, {
        delay: (index + 1) * 0.7,
        opacity: 0.5,
        duration: 1,
    });
});

- ScrollUp, ScrollDown 애니메이션

// 페이지 스크롤에 따른 요소 제어
const headerEl = document.querySelector('#header');
const toTopEl = document.querySelector('#to-top');

// 이전 스크롤 위치 저장 변수
let lastScrollY = window.scrollY;

window.addEventListener(
    'scroll',
    _.throttle(function () {
        // 현재 스크롤 위치
        const currentScrollY = window.scrollY;

        // 스크롤 다운
        if (currentScrollY > lastScrollY) {
            gsap.to(headerEl, {
                opacity: 0,
                display: 'none',
                duration: 0.6,
            });
            gsap.to(toTopEl, {
                right: '30px',
                duration: 0.2,
            });
        }
        // 스크롤 업
        else {
            gsap.to(headerEl, {
                opacity: 1,
                display: 'block',
                duration: 0.6,
            });
            gsap.to(toTopEl, {
                right: '-50px',
                duration: 0.2,
            });
        }

        // 이전 스크롤 위치 업데이트
        lastScrollY = currentScrollY;
    }, 300),
);

// 상단으로 스크롤 버튼을 클릭하면,
toTopEl.addEventListener('click', function () {
    // 페이지 위치를 최상단으로 부드럽게(0.7초 동안) 이동.
    gsap.to(window, {
        scrollTo: 0,
        duration: 0.7,
    });
});

// 순서대로 나타나는 기능
const fadeEls = document.querySelectorAll('.visual .fade-in');
fadeEls.forEach(function (fadeEl, index) {
    gsap.to(fadeEl, {
        delay: (index + 1) * 0.7,
        opacity: 1,
        duration: 1,
    });
});
티스토리 친구하기