Instruction

Webflow Template User Guide

GSAP Guide
Every GSAP code used on this template is here. How to edit them and find them is explain on this page. In every code block on this page, we added additional explanation to help you understand everything.

You can find the code in (Site settings) Footer Code.
Lenis Smooth Scroll
<script src="https://unpkg.com/lenis@1.3.1/dist/lenis.min.js"></script> 

 

<script>

// lenis smooth scroll
  
{
  let lenis;

  const initScroll = () => {
    lenis = new Lenis({});
    lenis.on("scroll", ScrollTrigger.update);
    gsap.ticker.add((time) => lenis.raf(time * 1000));
    gsap.ticker.lagSmoothing(0);
  };

  function initGsapGlobal() {
    
    // Do everything that needs to happen
    //  before triggering all
    // the gsap animations 

    initScroll();

    // match reduced motion media
    // const media = gsap.matchMedia();

    // Send a custom
    //  event to all your
    // gsap animations
    // to start them 

    const sendGsapEvent = () => {
      window.dispatchEvent(
        new CustomEvent("GSAPReady", {
          detail: {
            lenis,
          },
        })
      );
    };

    // Check if fonts are already loaded
    
    if (document.fonts.status === "loaded") {
      sendGsapEvent();
    } else {
      document.fonts.ready.then(() => {
        sendGsapEvent();
      });
    }

    // We need specific handling because the
    // grid/list changes the scroll height of the whole container
    //

    let resizeTimeout;
    const onResize = () => {
      clearTimeout(resizeTimeout);
      resizeTimeout = setTimeout(() => {
        ScrollTrigger.refresh();
      }, 50);
    };

    window.addEventListener("resize", () => onResize());
    const resizeObserver = new ResizeObserver((entries) => onResize());
    resizeObserver.observe(document.body);

    queueMicrotask(() => {
      gsap.to("[data-start='hidden']", {
        autoAlpha: 1,
        duration: 0.1,
        delay: 0.2,
      });
    });
  }

  // this only for dev
  
  const documentReady =
    document.readyState === "complete" || document.readyState === "interactive";

  if (documentReady) {
    initGsapGlobal();
  } else {
    addEventListener("DOMContentLoaded", (event) => initGsapGlobal());
  }
}

</script>
Lenis Smooth Scroll is a lightweight JavaScript library that enables buttery-smooth, hardware-accelerated scrolling for websites. It works by intercepting the browser’s native scroll behavior and applying eased, customizable motion, creating a more fluid and refined browsing experience. Lenis supports vertical and horizontal scroll, inertia effects, and syncs seamlessly with animations from libraries like GSAP or ScrollTrigger.
Service Slider GSAP Animation
Simple slider animation using GSAP
<script>
// Service slider  
gsap.registerPlugin(Draggable);

const gallery = document.querySelector(".about-service-gallery-slide");

Draggable.create(gallery, {
  type: "x",
  bounds: ".about-service-gallery", // container element
  inertia: true
});
// END Service slider
</script>
Work Slider GSAP Animation
Auto resize slider card using GSAP
<script>
document.addEventListener("DOMContentLoaded", () => {
  gsap.registerPlugin(Draggable);

  const slide = document.querySelector(".work-slide");
  const cards = document.querySelectorAll(".work-card");
  const images = document.querySelectorAll(".work-card-img");
  const wrapper = document.querySelector(".work-slide-wrapper");

  /* -------------------------------------------
        SIZE SETTINGS β€” RESPONSIVE
     ------------------------------------------- */
  let minW, maxW, minH, maxH;

  function setResponsiveSizes() {
    const w = window.innerWidth;

    if (w <= 480) {
      // πŸ“± MOBILE
      minW = 40;
      maxW = 70;
      minH = 60;
      maxH = 100;
    } else if (w <= 991) {
      // πŸ“² TABLET
      minW = 22;
      maxW = 32;
      minH = 28;
      maxH = 40;
    } else {
      // πŸ’» DESKTOP
      minW = 14;
      maxW = 20;
      minH = 20;
      maxH = 28;
    }
  }

  setResponsiveSizes();

  /* INITIAL STATE */
  gsap.set(slide, {
    display: "flex",
    alignItems: "flex-end",
    gap: "2vw"
  });

  gsap.set(cards, {
    overflow: "hidden",
    position: "relative"
  });

  gsap.set(images, {
    width: "100%",
    height: "100%",
    objectFit: "cover"
  });

  /* DRAGGABLE */
  const drag = Draggable.create(slide, {
    type: "x",
    bounds: getBounds(),
    inertia: false,
    onDrag: () => {
      updateBounds();
      updateSize();
    }
  })[0];

  /* DYNAMIC BOUNDS */
  function getBounds() {
    return {
      minX: -(slide.scrollWidth - window.innerWidth),
      maxX: 0
    };
  }

  function updateBounds() {
    drag.applyBounds(getBounds());
  }

  /* SIZE LOGIC */
  function updateSize() {
    const viewportCenter = window.innerWidth / 2;

    cards.forEach(card => {
      const rect = card.getBoundingClientRect();
      const cardCenter = rect.left + rect.width / 2;
      const dist = Math.abs(viewportCenter - cardCenter);

      const w = gsap.utils.mapRange(0, 400, maxW, minW, dist);
      const h = gsap.utils.mapRange(0, 400, maxH, minH, dist);

      gsap.to(card, {
        width: w + "vw",
        height: h + "vw",
        duration: 0.25,
        ease: "power3.out",
        overwrite: true
      });
    });
  }

  /* INIT */
  updateBounds();
  updateSize(); // resize right away when loaded

  window.addEventListener("resize", () => {
    setResponsiveSizes();  // <-- update size variant
    updateBounds();
    updateSize();
  });

  /* -------------------------------------------
        SCROLL NUDGE
     ------------------------------------------- */
  window.addEventListener("wheel", (e) => {
    const moveX = e.deltaY * 0.000001;
    const currentX = gsap.getProperty(slide, "x");
    const bounds = getBounds();

    let newX = currentX - moveX;
    newX = Math.min(bounds.maxX, Math.max(bounds.minX, newX));

    gsap.to(slide, {
      x: newX,
      duration: 0.35,
      ease: "power3.out"
    });

    updateSize();
  });

});
</script>
Header blending toggle Β GSAP Animation
Blending effect when open or close the menu
<script>
  document.addEventListener("DOMContentLoaded", () => {
  const openBtn = document.querySelector(".navbar-menu-button-open");
  const closeBtn = document.querySelector(".navbar-menu-button-close");
  const target = document.querySelector(".section-header.var-1");

  // OPEN β†’ NORMAL (instant)
  openBtn.addEventListener("click", () => {
    gsap.to(target, {
      duration: 0.2,
      
      onStart: () => {
        target.style.mixBlendMode = "normal";
      }
    });
  });

  // CLOSE β†’ EXCLUSION (with 0.5s delay)
  closeBtn.addEventListener("click", () => {
    gsap.to(target, {
      duration: 0.2,
      delay: 0.5,
      onStart: () => {
        target.style.mixBlendMode = "exclusion";
      }
    });
  });
});


</script>