패럴랙스 스크롤링은 웹사이트의 요소들이 서로 다른 속도로 움직이는 것
웹 페이지나 웹 앱에서 다양한 애니메이션 효과를 만들 수 있도록 도와주는 강력한 도구로 널리 사용됩니다.
<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 install gsap
npm install gsap@3.6.0
npm install gsap@3.6.0 scrolltrigger
gsap.to('요소', { 옵션, 시간 })
요소에 애니메이션을 적용
gsap.to()
: 현재 상태에서 시작하여 지정된 상태로 애니메이션을 적용
gsap.from()
: 지정된 상태에서 시작하여 현재 상태로 애니메이션을 적용
gsap.fromTo()
: 지정된 상태에서 시작하여 지정된 상태로 애니메이션을 적용
gsap.to(".box1", {
x: 400,
y: 400,
rotation: 45,
backgroundColor: "blue",
duration: 2,
});
gsap.timeline()
여러 개의 애니메이션을 순차적으로 실행
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 });
스크롤에 따라 요소에 애니메이션을 적용
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,
});
/**
* 페이지 스크롤에 따른 요소 제어
*/
// 페이지 스크롤에 영향을 받는 요소들을 검색!
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,
});
});
// 페이지 스크롤에 따른 요소 제어
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,
});
});