GSAP timeline examples -

Here is some text...

... and scroll trigger follows content ...

... till ...

THE END

        

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>

    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/Draggable.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/DrawSVGPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/EaselPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/Flip.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/GSDevTools.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/InertiaPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/MotionPathHelper.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/MotionPathPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/MorphSVGPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/Observer.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/Physics2DPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/PhysicsPropsPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/PixiPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrambleTextPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrollTrigger.min.js"></script>
    <!-- ScrollSmoother requires ScrollTrigger -->
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrollSmoother.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/ScrollToPlugin.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/SplitText.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/TextPlugin.min.js"></script>

    <!-- RoughEase, ExpoScaleEase and SlowMo are all included in the EasePack file -->    
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/EasePack.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/CustomEase.min.js"></script>
    <!-- CustomBounce requires CustomEase -->
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/CustomBounce.min.js"></script>
    <!-- CustomWiggle requires CustomEase -->
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/CustomWiggle.min.js"></script>
    <script>
    // use a script tag or an external JS file
    document.addEventListener("DOMContentLoaded", (event) => {
    gsap.registerPlugin(Draggable,DrawSVGPlugin,EaselPlugin,Flip,GSDevTools,InertiaPlugin,MotionPathHelper,MotionPathPlugin,MorphSVGPlugin,Observer,Physics2DPlugin,PhysicsPropsPlugin,PixiPlugin,ScrambleTextPlugin,ScrollTrigger,ScrollSmoother,ScrollToPlugin,SplitText,TextPlugin,RoughEase,ExpoScaleEase,SlowMo,CustomEase,CustomBounce,CustomWiggle)
    // gsap code here!
    });

    </script>
    <title>GSAP timeline examples - </title>
  </head>
  <body>
    <div class="main">
      <div class="pinned">
        <div class="horse">
          <img src="https://www.dziedziczak-artur.com//microblog/2024-01-28-02-04/images/index.jpeg" />
          <div class="grid">
            <div class="tile t1"></div>
            <div class="tile t2"></div>
            <div class="tile t3"></div>
            <div class="tile t4"></div>
            <div class="tile t5"></div>
          </div>
        </div>
        <div class="text-part">
          <h1 class="heading-1">Here is some text...</h1>
          <p class="heading-2">... and scroll trigger follows content ...</p>
          <p class="heading-3">... till ...</p>
        </div>
      </div>
    </div>
    <div class="end">
      <div class="heading-4">
        <img src="https://www.dziedziczak-artur.com/microblog/2025-06-08-15/images/index.jpeg" />
        <h1>THE END</h1>
      </div>
    </div>
    <script>
      const tl1 = gsap.timeline({
        scrollTrigger: {
                  trigger: ".main",
                  start: "top top", 
                  markers: true,
                  end: "bottom bottom", 
                  scrub: 1
                }
      });

      tl1.fromTo(".tile", {width: "0vw"}, { width: "50vw", stagger: {
        each: 0.1,
        from: "random"
      }})

      const tl2 = gsap.timeline({
        scrollTrigger: {
                  trigger: ".main",
                  start: "top top", 
                  markers: true,
                  end: "bottom bottom", 
                  scrub: 1
                }
      });

      tl2.to(".heading-1", {opacity: 1});
      tl2.to(".heading-2", {opacity: 1});
      tl2.to(".heading-3", {opacity: 1});

      const tl3 = gsap.timeline({
        scrollTrigger: {
                  trigger: ".end",
                  markers: { startColor: 'pink', endColor: 'purple'},
                  start: "top center", 
                  end: "center center", 
                  scrub: 1
                }
      });

      tl3.to(".heading-4", {opacity: 1});
    </script>
    <style>
    body {
      margin: 0;
      padding: 0;
    }
    .main {
      height: 600vh;
      width: 100%;
      position: relative;
    }
    .pinned {
      position: sticky;
      top: 0;
      width: 100%;
      height: 100vh;
      display: flex;
    }
    .horse img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100vh;
      object-contain: cover;
    }
    .text-part {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      width: 50%;
      height: 100vh;
    }
    .heading-1 {
      opacity: 0;
    }
    .heading-2 {
      opacity: 0;
    }
    .heading-3 {
      opacity: 0;
    }
    .heading-4 {
      opacity: 0;
    }
    .heading-4 h1 {
      position: relative;
      color: white;
    }
    .end img {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100vh;
    }
    .end {
      position: relative;
      height: 100vh;
      width: 100%;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    .horse {
      position: relative;
      top: 0;
      width: 50vw;
      overflow: hidden;
      display: flex;
      flex-direction: row;
    }
    .grid {
      position: relative;
      top: 0;
      left: 0;
      display: flex;
      flex-gap: 0px;
      flex-direction: column;
      flex-wrap: wrap;
      width: 100%;
      height: 100vh;
    }
    .tile {
      cursor: pointer;
      display: flex;
      justify-content: center;
      align-items: center;
      position: relative;
      width: 0vw;
      height: 20vh;
      backdrop-filter: invert(100%);
    }
    </style>
  </body>
</html>