Tab Change Animation

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

  const tabs = gsap.utils.toArray(".product-content-box .w-tab-link");
  const bars = gsap.utils.toArray(".product-content-box .line");

  const DURATION = 5;

  let tween;

  let current = tabs.findIndex(tab =>
    tab.classList.contains("w--current")
  );

  if (current === -1) current = 0;

  gsap.set(bars, {
    width: "0%",
    transformOrigin: "left center"
  });

  function updateTextColor(index){

    // সব text default color
    gsap.to(".product-content-box .tab-item-text", {
      color: "#A0A0A0", // তোমার default color
      duration: 0.25
    });

    // Active tab text white
    gsap.to(tabs[index].querySelectorAll(".tab-item-text"), {
      color: "#FFFFFF",
      duration: 0.25
    });

  }

  function startProgress(index) {

    if (tween) tween.kill();

    current = index;

    gsap.set(bars, { width: "0%" });

    // Update active text color
    updateTextColor(current);

    tween = gsap.to(bars[current], {
      width: "100%",
      duration: DURATION,
      ease: "none",
      onComplete: () => {
        const next = (current + 1) % tabs.length;
        tabs[next].click();
      }
    });

  }

  tabs.forEach((tab, i) => {
    tab.addEventListener("click", () => {
      startProgress(i);
    });
  });

  startProgress(current);

});
</script>

Tab Change Animation Two

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

  const tabButtons = document.querySelectorAll(".faq-menu-box .tab-button");

  function updateButtonShade() {
    gsap.set(".faq-menu-box .button-shade", {
      opacity: 0,
      scale: 0.8
    });

    const activeShade = document.querySelector(
      ".faq-menu-box .tab-button.w--current .button-shade"
    );

    if (activeShade) {
      gsap.to(activeShade, {
        opacity: 1,
        scale: 1,
        duration: 0.4,
        ease: "power2.out"
      });
    }
  }

  updateButtonShade();

  tabButtons.forEach(btn => {
    btn.addEventListener("click", () => {
      setTimeout(updateButtonShade, 50); // Webflow current class update wait
    });
  });

});
</script>

Tab Change Animation Three

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

  const tabs = document.querySelectorAll(".product-tab-box .tab-title-item");

  function updateBlur() {

    // Hide all blur images
    gsap.set(".product-tab-box .button-blur", {
      autoAlpha: 0,
      scale: 0.9
    });

    // Show only active tab blur
    const activeBlur = document.querySelector(
      ".product-tab-box .tab-title-item.w--current .button-blur"
    );

    if (activeBlur) {
      gsap.to(activeBlur, {
        autoAlpha: 1,
        scale: 1,
        duration: 0.35,
        ease: "power2.out"
      });
    }
  }

  updateBlur();

  tabs.forEach(tab => {
    tab.addEventListener("click", () => {
      setTimeout(updateBlur, 50); // Wait for Webflow to add w--current
    });
  });

});
</script>

Tab Change Animation Four

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

  const tabs = gsap.utils.toArray(".solution-box-item");

  // Initial State
  tabs.forEach(tab => {
    const details = tab.querySelector(".solution-details-text-wrap");

    gsap.set(details, {
      overflow: "hidden",
      height: tab.classList.contains("w--current")
        ? details.scrollHeight
        : 0
    });

    gsap.set(tab.querySelector(".solution-details"), {
      color: tab.classList.contains("w--current") ? "#fff" : ""
    });

    gsap.set(tab.querySelectorAll('[class*="gradient-"]'), {
      autoAlpha: tab.classList.contains("w--current") ? 1 : 0
    });

    gsap.set(tab.querySelectorAll('[class*="white-"]'), {
      autoAlpha: tab.classList.contains("w--current") ? 0 : 1
    });
  });

  function updateTabs() {

    tabs.forEach(tab => {

      const details = tab.querySelector(".solution-details-text-wrap");
      const text = tab.querySelector(".solution-details");

      if (tab.classList.contains("w--current")) {

        gsap.killTweensOf(details);

        gsap.to(details,{
          height: details.scrollHeight,
          duration: .45,
          ease: "power2.out",
          overwrite: true,
          onComplete:()=> gsap.set(details,{height:"auto"})
        });

        gsap.to(text,{
          color:"#fff",
          duration:.25
        });

        gsap.to(tab.querySelectorAll('[class*="gradient-"]'),{
          autoAlpha:1,
          duration:.25
        });

        gsap.to(tab.querySelectorAll('[class*="white-"]'),{
          autoAlpha:0,
          duration:.25
        });

      } else {

        gsap.killTweensOf(details);

        gsap.set(details,{
          height:details.offsetHeight
        });

        gsap.to(details,{
          height:0,
          duration:.35,
          ease:"power2.inOut",
          overwrite:true
        });

        gsap.to(text,{
          color:"",
          duration:.25
        });

        gsap.to(tab.querySelectorAll('[class*="gradient-"]'),{
          autoAlpha:0,
          duration:.25
        });

        gsap.to(tab.querySelectorAll('[class*="white-"]'),{
          autoAlpha:1,
          duration:.25
        });

      }

    });

  }

  const observer = new MutationObserver(updateTabs);

  tabs.forEach(tab=>{
    observer.observe(tab,{
      attributes:true,
      attributeFilter:["class"]
    });
  });

});
</script>

Counter Animation

<script>
gsap.registerPlugin(ScrollTrigger);

gsap.utils.toArray(".counter").forEach(counter => {

  const finalText = counter.textContent.trim();

  const endValue = parseFloat(finalText.replace(/[^0-9.-]/g, ""));
  const suffix = finalText.replace(/[0-9.-]/g, "");
  const decimals = finalText.includes(".") ? 1 : 0;

  // Reset to zero
  counter.textContent = "0" + suffix;

  const obj = { value: 0 };

  gsap.to(obj, {
    value: endValue,
    duration: 2,
    ease: "power2.out",
    scrollTrigger: {
      trigger: counter,
      start: "top 80%",
      once: true
    },
    onUpdate() {
      counter.textContent =
        obj.value.toFixed(decimals) + suffix;
    }
  });

});
</script>

Smooth Scroll Animation

<script>
// Initialize Lenis with better settings
const lenis = new Lenis({
  duration: 1, // Animation duration in seconds
  easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // Smooth easing
  direction: 'vertical', // vertical, horizontal
  gestureDirection: 'vertical', // vertical, horizontal, both
  smooth: true,
  mouseMultiplier: 1,
  smoothTouch: false, // Disable on touch devices if you prefer
  touchMultiplier: 2,
  infinite: false,
});

// Sync with ScrollTrigger if you're using GSAP animations
lenis.on('scroll', ScrollTrigger.update);

// Add scroll event listeners for any custom behaviors
lenis.on('scroll', (e) => {
  console.log(e); // Remove this in production
});

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

requestAnimationFrame(raf);

// Force Lenis to recalculate on resize
window.addEventListener('resize', () => {
  lenis.resize();
});

// Handle hash links (anchor links)
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
  anchor.addEventListener('click', function (e) {
    e.preventDefault();
    const targetId = this.getAttribute('href');
    if (targetId === '#') return;
    
    const targetElement = document.querySelector(targetId);
    if (targetElement) {
      lenis.scrollTo(targetElement, {
        offset: -100, // Adjust offset if you have fixed header
        duration: 1.2
      });
    }
  });
});
</script>
BG ImageBG ImageBG ImageIconImage