GSAP - ScrollTrigger

by Hugo Vale Pereira

HTML

<!--Tutorial from: https://www.youtube.com/watch?v=Gy9IS0Y6dy0  Nov 2025
inspired from: https://www.wildyriftian.com/works
-->

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.13.0/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ScrollTrigger.min.js"></script>
<nav>
  <p>Tutorial</p>
  <p>GSAP</p>
</nav>

<!-- <div class="container">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
  <div class="box">4</div>
</div> -->



<div class="wrapper">
    <div class="container">
      <div class="panel">Panel 1</div>
      <div class="panel">Panel 2</div>
      <div class="panel">Panel 3</div>
      <div class="panel">Panel 4</div>
    </div>
  </div>

CSS

@import url('https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap');
/* 
:root {
  --bg: #dddddd;
  --fg: #1d1d1d;
  --variant-1: oklch(0.9412 0.2245 111.18);
  --variant-2: oklch(0.6647 0.2695 31.76);
  --variant-3: #bdbdbd;
  --disabled-folder-bg: #d2d2d2;
  --disabled-folder-fg: #8a8a8a;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

* {
  outline: #1d1d1d 1px dashed;
}

body {
  background: var(--bg);
  color: var(--fg);
}


h1{
  font-family: "DM Sans" ,-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
  font-size: 2.75rem;
  font-weight: 400;

}

p{
  text-transform: uppercase;
  font-family: "DM Mono";
  font-size: 0.8rem;
  font-weight: 500;
}



h1,
p {
  transition: color 250ms ease;
}

nav {
  position: absolute;
  top: 0;
  width: 100%;
  padding: 2rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.container{
  margin-top: 20vh;
  
  display: flex;
  

  gap: 1rem;
}


.box{
  flex-shrink: 0;
  height: 100px;
  width: 100px;
  background: var(--variant-1);
 

}



.container {
  -webkit-overflow-scrolling: touch; //Smooth scroll on ios
  scrollbar-width: thin;
}*/





 body {
      margin: 0;
      overflow-x: hidden;
    }
    
    .wrapper {
      height: 100vh;
      overflow: hidden;
    }
    
    .container {
      display: flex;
      width: fit-content;
      height: 100vh;
    }
    
    .panel {
      width: 100vw;
      height: 100vh;
      flex-shrink: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 3rem;
    }
    
    .panel:nth-child(1) { background: #e74c3c; }
    .panel:nth-child(2) { background: #3498db; }
    .panel:nth-child(3) { background: #2ecc71; }
   ...

JavaScript

gsap.registerPlugin(ScrollTrigger)


gsap.to(".container", {
  x: () => -(document.querySelector(".container").scrollWidth - window.innerWidth),
  ease: "none",
  scrollTrigger: {
    trigger: ".wrapper",
    pin: true,
    scrub: 1,
    end: () => `+=${document.querySelector(".container").scrollWidth}`
  }
});