[해피CGI][cgimall] 가로 스크롤 갤러리- Horizontal Scrolling Gallery with ScrollTrigger
스크롤트리거를 활용한 가로 스크롤 갤러리
Horizontal Scrolling Gallery with ScrollTrigger (GSAP 예제)
GSAP ScrollTrigger를 활용해 세로 스크롤을 가로 스크롤 애니메이션으로 변환한 이미지 갤러리 데모.
이 예제는 GreenSock Animation Platform(GSAP)의 ScrollTrigger 플러그인을 이용하여, 사용자의 세로 스크롤 동작을 가로 방향으로 변환해 주는 가로 스크롤 갤러리를 구현합니다.

HTML 구조
<div id="smooth-wrapper">
<div id="smooth-content">
<section class="panel plain">
<h3>Scroll down for the Gallery</h3>
</section>
<section id="portfolio">
<div class="container-fluid">
<div class="horiz-gallery-wrapper">
<div class="horiz-gallery-strip">
<div class="project-wrap">
</div>
<div class="project-wrap">
</div>
<div class="project-wrap">
</div>
<div class="project-wrap">
</div>
<div class="project-wrap">
</div>
<div class="project-wrap">
</div>
<div class="project-wrap">
</div>
<div class="project-wrap">
</div>
</div>
</div>
</div>
</section>
<section class="panel plain">
<h3>That's it!</h3>
</section>
</div>
</div>
CSS 소스
body {
overflow-x: hidden;
margin: 0;
}
.row,
.section,
section {
position: relative;
overflow: hidden;
}
.section,
section {
text-align: center;
}
.container-fluid {
width: 100%;
padding-right: 0;
padding-left: 0;
margin-right: auto;
margin-left: auto;
}
.horiz-gallery-strip,
.horiz-gallery-wrapper {
display: flex;
flex-wrap: nowrap;
will-change: transform;
position: relative;
}
.project-wrap {
width: 33vw;
padding: 2rem;
box-sizing: content-box;
}
.project-wrap img {
width: 100%;
aspect-ratio: 1/1;
object-fit: cover;
}
JS 소스
gsap.registerPlugin(ScrollTrigger, ScrollSmoother);
const smoother = ScrollSmoother.create({
wrapper: "#smooth-wrapper",
content: "#smooth-content",
smooth: 2,
normalizeScroll: true,
ignoreMobileResize: true,
preventDefault: true
});
//Horizontal Scroll Galleries
if (document.getElementById("portfolio")) {
const horizontalSections = gsap.utils.toArray(".horiz-gallery-wrapper");
horizontalSections.forEach(function (sec, i) {
const pinWrap = sec.querySelector(".horiz-gallery-strip");
let pinWrapWidth;
let horizontalScrollLength;
function refresh() {
pinWrapWidth = pinWrap.scrollWidth;
horizontalScrollLength = pinWrapWidth - window.innerWidth;
}
refresh();
// Pinning and horizontal scrolling
gsap.to(pinWrap, {
scrollTrigger: {
scrub: true,
trigger: sec,
pin: sec,
start: "center center",
end: () => `+=${pinWrapWidth}`,
invalidateOnRefresh: true
},
x: () => -horizontalScrollLength,
ease: "none"
});
ScrollTrigger.addEventListener("refreshInit", refresh);
});
}
