Counter Animation with GSAP

What It does

This animates counters to count up from 0 on scroll.

HTML Requirements

   // ============================================
    // COUNTER ANIMATION WITH GSAP
    // ============================================

    function initCounterAnimations() {
        const counterElements = document.querySelectorAll(".counter");

        counterElements?.forEach(counterItem => {
            gsap.from(counterItem, {
                textContent: 0,
                duration: 4,
                ease: "power1.in",
                snap: { textContent: 1 },
                scrollTrigger: {
                    trigger: counterItem,
                    start: "top 95%",
                    once: true
                },
                onUpdate: function () {
                    const counterValue = Math.ceil(parseInt(counterItem.textContent) || 0);
                    counterItem.textContent = counterValue.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
                }
            });
        });
    }

    // ============================================
    // INITIALIZE ANIMATIONS ON PAGE LOAD
    // ============================================
    document.addEventListener('DOMContentLoaded', function () {
        initCounterAnimations();
    });
Code Block 1

Element Map

  • .counter: Text animates from 0 to value, with commas.

Customizing Key Variables

  • Duration: 4 → 6 for slower.

    duration: 6
  • Reveal: 0.5 → 0.7.

    duration: 0.7
  • Ease: "power1.in" → "power2.inOut".

    ease: "power2.inOut"
  • Start: "top 95%" → "top 80%" for delayed trigger.

    start: "top 80%"

Removing Animations

  • Comment/Remove: The code from site settings that are shown in Code Block 7

Lenis Smooth Scrolling

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

// Initialize Lenis smooth scroll
const lenis = new Lenis({
    duration: 1.2,
    easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
    smooth: true
    });
    
    // Connect Lenis to GSAP ScrollTrigger
    lenis.on('scroll', ScrollTrigger.update);
    
    gsap.ticker.add((time) => {
    lenis.raf(time * 1000);
});
    
gsap.ticker.lagSmoothing(0);

});