Instruction

Guide for Fluke Webflow Template

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.
About Section GSAP Animation
GSAP animation of image card sliding up continously
<script>

//About Section
// Image Card Loop
const items = document.querySelectorAll(".project-card");
const offset = 30;

gsap.set(items, {
  zIndex: (index) => items.length - index,
  opacity: 0,
  scale: 0.8
});

// ------------------ Diagonal Loop (Desktop, unchanged) ------------------ //
function diagonalLoop(items) {
  let totalItems = items.length;
  let currentItem = 0;

  function updatePositions() {
    for (let i = 0; i < totalItems; i++) {
      let itemIndex = (currentItem + i) % totalItems;
      let item = items[itemIndex];
      gsap.to(item, {
        x: offset * i,
        y: -offset * i * 1.5, // ⬆️ diagonal upward
        zIndex: totalItems - i,
        scale: 1,
        opacity: 1,
        duration: 0.6
      });
    }
  }

  function moveToNext() {
    currentItem = (currentItem + 1) % totalItems;
    updatePositions();
  }

  updatePositions();
  setInterval(moveToNext, 2000);
}

// ------------------ Straight Loop (Mobile, fixed to stack upward) ------------------ //
function straightLoop(items) {
  let totalItems = items.length;
  let currentItem = 0;

  function updatePositions() {
    for (let i = 0; i < totalItems; i++) {
      let itemIndex = (currentItem + i) % totalItems;
      let item = items[itemIndex];
      gsap.to(item, {
        x: 0,
        y: -offset * i * 1.5, // ⬆️ straight upward (TOP visible first)
        zIndex: totalItems - i,
        scale: 1,
        opacity: 1,
        duration: 0.6
      });
    }
  }

  function moveToNext() {
    currentItem = (currentItem + 1) % totalItems;
    updatePositions();
  }

  updatePositions();
  setInterval(moveToNext, 2000);
}

// ------------------ Responsive Setup ------------------ //
document.addEventListener("DOMContentLoaded", function () {
  gsap.registerPlugin(ScrollTrigger);

  ScrollTrigger.create({
    trigger: ".about-scroll-trigger",
    start: "top 80%",
    once: true,
    onEnter: () => {
      if (window.innerWidth <= 428) {
        straightLoop(items); // 📱 Mobile → stacked upward (top peeks out)
      } else {
        diagonalLoop(items); // 💻 Desktop → original diagonal upward
      }
    }
  });
});
// END Image Card Loop

  

</script>
Why Us Section GSAP Animation
Featuring number counter
<script>

  
//WHY US SECTION
// Counter
gsap.registerPlugin(ScrollTrigger);

document.querySelectorAll(".why-us-card").forEach(card => {
  let counter = card.querySelector(".number");

  if (counter) {
    let finalValue = parseInt(counter.textContent, 10);

    // Set initial value to 0
    counter.textContent = "0";

    ScrollTrigger.create({
      trigger: card,
      start: "top 80%", // when each card reaches 80% down the viewport
      once: true,
      onEnter: () => {
        gsap.fromTo(counter, 
          { innerText: 0 }, 
          {
            innerText: finalValue,
            duration: 2,
            ease: "power1.out",
            snap: { innerText: 1 }
          }
        );
      }
    });
  }
});

// END Counter
  
</script>