GSAP 패럴랙스 이펙트 : 가로/세로 효과
소개
안녕하세요! 웹스토리보이입니다. 가로 효과를 무사히 작업하였다면, 이제는 가로 세로 효과를 작업해보겠습니다. 가로와 세로가 결합된 형태이기 때문에 가로 효과보다는 조금 더 어려울 수 있습니다. 처음부터 가로 효과가 아닌 원하는 섹션만 가로 효과로 만들어야 하기 때문에 그 부분만 가로로 CSS 셋팅이 먼저 되어 있어야 합니다. 그럼 한번 만들어볼까요? 🙀
1. 기본 구조 만들기
1-1. 준비하기
GSAP를 배우는 시간이기 때문에 HTML/CSS 코딩은 생략하겠습니다. 기본 코딩은 복사해서 사용하겠습니다. 우선 웹폰트를 설정하고 GSAP에서 필요한 파일을 미리 셋팅해 놓겠습니다. GSAP는 자주 업데이트가 되기 때문에 제일 최선 버전을 사용하는게 좋습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GSAP Scroll Effect</title>
<!-- 웹폰트 설정 -->
<link href="https://webfontworld.github.io/NexonLv1Gothic/NexonLv1Gothic.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@100&display=swap" rel="stylesheet">
</head>
<body>
<!-- GSAP 라이브러리 설정 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.1/ScrollToPlugin.min.js"></script>
</body>
</html>
1-2. 기본 셋팅하기
소스는 그대로 복사해서 사용하겠습니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>GSAP Scroll Effect</title>
<link href="https://webfontworld.github.io/NexonLv1Gothic/NexonLv1Gothic.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Lato:wght@100&display=swap" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
}
a {
color: #fff;
text-decoration: none;
}
body {
color: #fff;
font-family: "NexonLv1Gothic";
font-weight: 300;
background-color: #333;
}
#parallax__title {
position: fixed;
left: 20px;
top: 20px;
z-index: 1000;
}
#parallax__title h1 {
font-size: 30px;
border-bottom: 1px dashed #fff;
margin-bottom: 10px;
padding-bottom: 5px;
font-weight: 400;
display: inline-block;
}
#parallax__title p {
font-size: 16px;
}
#parallax__title ul {
margin-top: 10px;
}
#parallax__title li {
display: inline;
}
#parallax__title li a {
width: 20px;
height: 20px;
border-radius: 50%;
border: 1px dashed #fff;
display: inline-block;
text-align: center;
line-height: 20px;
font-size: 12px;
}
#parallax__title li.active a {
background: #fff;
color: #000;
}
/* parallax__cont */
.parallax__item {
width: 100%;
height: 100vh;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.parallax__item__num {
font-size: 5vw;
position: absolute;
right: 20px;
bottom: 20px;
font-family: "Lato";
font-weight: 100;
z-index: 100;
}
.parallax__item__imgWrap {
width: 30%;
padding-bottom: 18%;
position: relative;
overflow: hidden;
border-radius: 10px;
}
.parallax__item__img {
position: absolute;
left: -5%;
top: -5%;
width: 110%;
height: 110%;
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
filter: saturate(0%);
transition: all 1s;
}
.parallax__item__img:hover {
filter: saturate(100%);
transform: scale(1.025);
}
#section1 .parallax__item__img {
background-image: url(assets/img/images01@2.jpg);
}
#section2 .parallax__item__img {
background-image: url(assets/img/images02@2.jpg);
}
#section3 .parallax__item__img {
background-image: url(assets/img/images03@2.jpg);
}
#section4 .parallax__item__img {
background-image: url(assets/img/images04@2.jpg);
}
#section5 .parallax__item__img {
background-image: url(assets/img/images05@2.jpg);
}
#section6 .parallax__item__img {
background-image: url(assets/img/images06@2.jpg);
}
#section7 .parallax__item__img {
background-image: url(assets/img/images07@2.jpg);
}
#section8 .parallax__item__img {
background-image: url(assets/img/images08@2.jpg);
}
#section9 .parallax__item__img {
background-image: url(assets/img/images09@2.jpg);
}
#section1, #section3, #section5, #section7, #section9 {
background-color: #111;
}
/* option */
</style>
</head>
<body>
<header id="parallax__title">
<h1>GSAP Parallax Effect13</h1>
<p>GSAP scrollTrigger - 가로/세로 효과</p>
<ul>
<li><a href="gsap01.html">1</a></li>
<li><a href="gsap02.html">2</a></li>
<li><a href="gsap03.html">3</a></li>
<li><a href="gsap04.html">4</a></li>
<li><a href="gsap05.html">5</a></li>
<li><a href="gsap06.html">6</a></li>
<li><a href="gsap07.html">7</a></li>
<li><a href="gsap08.html">8</a></li>
<li><a href="gsap09.html">9</a></li>
<li><a href="gsap10.html">10</a></li>
<li><a href="gsap11.html">11</a></li>
<li><a href="gsap12.html">12</a></li>
<li class="active"><a href="gsap13.html">13</a></li>
<li><a href="gsap14.html">14</a></li>
<li><a href="gsap15.html">15</a></li>
</ul>
</header>
<!-- //parallax__title -->
<main id="parallax__cont">
<section id="section1" class="parallax__item">
<span class="parallax__item__num">01</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section1 -->
<section id="section2" class="parallax__item">
<span class="parallax__item__num">02</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section2 -->
<main id="horizontal">
<section id="section3" class="parallax__item">
<span class="parallax__item__num">03</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section3 -->
<section id="section4" class="parallax__item">
<span class="parallax__item__num">04</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section4 -->
<section id="section5" class="parallax__item">
<span class="parallax__item__num">05</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section5 -->
<section id="section6" class="parallax__item">
<span class="parallax__item__num">06</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section6 -->
<section id="section7" class="parallax__item">
<span class="parallax__item__num">07</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section7 -->
</main>
<section id="section8" class="parallax__item">
<span class="parallax__item__num">08</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section8 -->
<section id="section9" class="parallax__item">
<span class="parallax__item__num">09</span>
<figure class="parallax__item__imgWrap">
<div class="parallax__item__img"></div>
</figure>
</section>
<!-- //section9 -->
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.1/ScrollToPlugin.min.js"></script>
<script>
</script>
</body>
</html>
2. 스크립트 작업하기
2-1. 작업하기
먼저 CSS 셋팅을 해야 합니다. 원하는 가로 영역을 #horizontal
로 감싸고 다음과 같이 셋팅을 합니다. 5개의 섹션을 작업할 것이기 때문에 500vw
로 설정햇습니다.
#parallax__cont {
overflow: hidden;
}
#horizontal {
display: flex;
flex-wrap: nowrap;
width: 500%;
}
#horizontal > section {
width: 100%;
}
먼저, const horizontal = document.querySelector("#horizontal");은 #horizontal ID를 가진 요소를 선택하여 horizontal 변수에 저장합니다. 이 요소는 스크롤 트리거로 사용될 것입니다. 다음으로, gsap.utils.toArray("#horizontal > section")은 #horizontal 요소 내부에 있는 모든 section 요소를 선택하여 배열로 반환하는 코드입니다. 선택된 요소들은 section
변수에 저장됩니다.
gsap.to()
메서드를 사용하여 선택한 section 요소들에 대한 애니메이션을 정의합니다. xPercent: -100 * (section.length - 1)은 section 배열 내의 요소들을 가로 축으로 이동시키는 애니메이션 속성입니다. -100 * (section.length - 1)은 마지막 요소를 제외한 모든 요소들을 왼쪽으로 100%만큼 이동시킵니다. ease: "none"
은 애니메이션의 움직임을 부드럽게 하는 이징 효과를 적용하지 않는 것을 의미합니다.
scrollTrigger 객체는 스크롤 이벤트와 관련된 설정을 정의하며, trigger: horizontal
은 스크롤 트리거로 사용될 요소를 지정합니다. 위에서 선택한 horizontal 요소를 지정했습니다. start: "top top"
은 트리거 요소가 스크롤되기 시작하는 시점을 지정합니다. 여기서는 스크롤이 맨 위로 이동했을 때를 의미합니다.
end: () => "+=" + (horizontal.offsetWidth - innerWidth)는 애니메이션이 끝나는 시점을 지정하는 옵션입니다. horizontal.offsetWidth - innerWidth는 horizontal 요소의 너비에서 현재 뷰포트의 너비를 뺀 값으로, 애니메이션이 끝나는 지점을 설정합니다. pin: true는 스크롤 트리거 요소를 고정시키는 옵션입니다. 즉, 트리거 요소가 스크롤되면서 다른 요소들이 지나가는 것처럼 보이게 됩니다.
scrub: 1
은 트리거 요소가 스크롤되는 동안 애니메이션을 부드럽게 진행하기 위한 옵션입니다. snapTo: 1 / (section.length - 1)
은 스크롤 위치를 요소들의 위치에 스냅하는 옵션입니다. 1 / (section.length - 1)은 각 요소 사이의 스냅 간격을 설정합니다. inertia: false
는 스냅 시의 관성 효과를 비활성화합니다. duration: {min: 0.1, max: 0.1}
은 스냅 애니메이션의 최소 및 최대 지속 시간을 설정합니다. invalidateOnRefresh: true
는 페이지 새로고침 시 스크롤 트리거 위치를 재계산하도록 설정합니다. anticipatePin: 1
은 스크롤 트리거 요소의 위치를 예측하여 부드럽게 고정하는 옵션입니다.
const horizontal = document.querySelector("#horizontal");
const sections = gsap.utils.toArray("#horizontal > section");
gsap.to(section, {
xPercent: -100 * (sections.length - 1),
ease: "none",
scrollTrigger: {
trigger: horizontal,
start: "top top",
end: () => "+=" + (horizontal.offsetWidth - innerWidth),
pin: true,
scrub: 1,
snap: {
snapTo: 1 / (sections.length - 1),
inertia: false,
duration: {min: 0.1, max: 0.1}
},
invalidateOnRefresh: true,
anticipatePin: 1
}
});
3. 마무리
조금 어려운 부분들이 나오기는 했지만, 이렇게 하면 세로 / 가로 모드가 완성됩니다. 최대한 간단하게 스크립트를 구성하였고, 포폴 만드는데 크게 어려움이 없을거라고 생각이 듭니다. 지금가지 가로 모드, 세로가로 모드를 완성하였습니다. 그럼 이렇게 만든 모드에서 애니메이션까지 나타나게 하면 완벽하겠죠^^ 지금까지 배웠던 것을 접목시키면 훌륭한 패럴랙스 사이트가 완성될 겁니다. 수고하셨습니다. 🥱
예제 목록
- 1. GSAP 패럴랙스 이펙트 : 기본 애니메이션
- 2. GSAP 패럴랙스 이펙트 : Pin 애니메이션
- 3. GSAP 패럴랙스 이펙트 : Pin 배경 고정하기
- 4. GSAP 패럴랙스 이펙트 : 이질감 효과
- 5. GSAP 패럴랙스 이펙트 : 나타나기 효과
- 6. GSAP 패럴랙스 이펙트 : 텍스트 효과
- 7. GSAP 패럴랙스 이펙트 : 배경색 효과
- 8. GSAP 패럴랙스 이펙트 : 진행바 효과
- 9. GSAP 패럴랙스 이펙트 : 메뉴 이동 효과
- 10. GSAP 패럴랙스 이펙트 : 메뉴 축소 효과
- 11. GSAP 패럴랙스 이펙트 : 메뉴 숨기기 효과
- 12. GSAP 패럴랙스 이펙트 : 가로 효과
- 13. GSAP 패럴랙스 이펙트 : 가로/세로 효과
- 14. GSAP 패럴랙스 이펙트 : 가로/세로 나타나기 효과
- 15. GSAP 패럴랙스 이펙트 : 스무스 효과
댓글