Instructions

Lenis Smooth Scrolling

This provides smooth scrolling across the entire template. To turn off just comment out this code.

<link rel="stylesheet" href="https://unpkg.com/lenis@1.3.20/dist/lenis.css" />
<script src="https://unpkg.com/lenis@1.3.20/dist/lenis.min.js"></script> 
<script>
  gsap.registerPlugin(ScrollTrigger);

  const lenis = new Lenis({
    duration: 1.5,
    easing: (t) => 1 - Math.pow(1 - t, 3),
    smooth: true,
    smoothTouch: false, // ✅ important
  });

  // sync
  lenis.on('scroll', ScrollTrigger.update);

  // raf loop
  function raf(time) {
    lenis.raf(time);
    requestAnimationFrame(raf);
  }
  requestAnimationFrame(raf);

  // ✅ correct scroller
  ScrollTrigger.scrollerProxy(document.documentElement, {
    scrollTop(value) {
      return arguments.length ? lenis.scrollTo(value, { immediate: true }) : lenis.scroll;
    },
    getBoundingClientRect() {
      return {
        top: 0,
        left: 0,
        width: window.innerWidth,
        height: window.innerHeight,
      };
    },
  });

  // ✅ important
  ScrollTrigger.defaults({
    scroller: document.documentElement,
  });

  // refresh fix
  ScrollTrigger.addEventListener('refresh', () => lenis.resize());

  ScrollTrigger.refresh();
</script>

Auto-Switching Testimonial Tabs with GSAP

Tabs automatically switch every 3 seconds, creating a dynamic user experience without user interaction.

<script>
window.addEventListener("load", () => {

  const tabs = gsap.utils.toArray(".testimonial-tabs-link");

  let duration = 3;
  let tween;
  let autoPlay;

  function getItems(){
    return tabs.map(tab => tab.querySelector(".background-color"));
  }

  function resetOpacity(){
    getItems().forEach(el => gsap.set(el,{opacity:0}));
  }

  function getActiveIndex(){
    return tabs.findIndex(tab => tab.classList.contains("w--current"));
  }

  function goToTab(index){
    if(index < 0) return;
    tabs[index].click();
  }

  function startAnimation(i){

    if(i < 0) return;

    // stop previous animation + autoplay
    if(tween) tween.kill();
    if(autoPlay) autoPlay.kill();

    let items = getItems();

    // hide all
    gsap.to(items,{
      opacity:0,
      duration:0.3
    });

    // active fade in
    tween = gsap.to(items[i],{
      opacity:1,
      duration:0.6,
      ease:"power2.out"
    });

    // autoplay next
    autoPlay = gsap.delayedCall(duration, ()=>{
      let next = (i + 1) % tabs.length;
      goToTab(next);
    });
  }

  // click event
  tabs.forEach((tab)=>{
    tab.addEventListener("click",()=>{
      let index = tabs.indexOf(tab);
      startAnimation(index);
    });
  });

  // initial setup
  let initialIndex = getActiveIndex();

  if(initialIndex < 0){
    initialIndex = 0;
    goToTab(0);
  }

  resetOpacity();
  let items = getItems();
  gsap.set(items[initialIndex],{opacity:1});

  // start auto
  startAnimation(initialIndex);

});
</script>

Infinite Directional Motion Animation with GSAP

This script creates a continuous, seamless motion system using GSAP (GreenSock Animation Platform). Elements move infinitely across both horizontal and vertical directions, producing a dynamic and engaging visual effect.

<script>
gsap.registerPlugin();

/* Top Left → Left to Right */
gsap.to(".top-left",{
  x:"100vw",
  duration:10,
  repeat:-1,
  ease:"none"
});

/* Bottom Right → Right to Left */
gsap.to(".bottom-right",{
  x:"-100vw",
  duration:10,
  repeat:-1,
  ease:"none"
});

/* Top Right Vertical → Top to Bottom */
gsap.to(".top-right-vertical",{
  y:"100vh",
  duration:10,
  repeat:-1,
  ease:"none"
});

/* Bottom Left Vertical → Bottom to Top */
gsap.to(".bottom-left-vertical",{
  y:"-100vh",
  duration:10,
  repeat:-1,
  ease:"none"
});
</script>