<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>
window.Webflow = window.Webflow || [];
window.Webflow.push(() => {
gsap.registerPlugin(ScrollTrigger);
// =========================
// Lenis
// =========================
const lenis = new Lenis({
duration: 0.9,
easing: (t) => 1 - Math.pow(1 - t, 3),
smoothWheel: true,
touchMultiplier: 1,
wheelMultiplier: 1
});
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
lenis.on("scroll", ScrollTrigger.update);
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
};
}
});
ScrollTrigger.defaults({
scroller: document.documentElement
});
ScrollTrigger.addEventListener("refresh", () => {
lenis.resize();
});
// =========================
// SCROLL COUNTER
// Attribute:
// counter-animation
// =========================
document.querySelectorAll("[counter-animation]").forEach(counter => {
const text = counter.textContent.trim();
const match = text.match(/-?\d[\d,]*(\.\d+)?/);
if (!match) return;
const rawNumber = match[0];
const number = parseFloat(rawNumber.replace(/,/g, ""));
const prefix = text.slice(0, match.index);
const suffix = text.slice(match.index + rawNumber.length);
const decimals = rawNumber.includes(".")
? rawNumber.split(".")[1].length
: 0;
const obj = { value: 0 };
gsap.to(obj, {
value: number,
duration: 2,
ease: "power3.out",
snap: {
value: decimals
? Math.pow(10, -decimals)
: 1
},
scrollTrigger: {
trigger: counter,
start: "top 85%",
once: true
},
onUpdate() {
const value = decimals
? obj.value.toFixed(decimals)
: Math.round(obj.value).toLocaleString();
counter.textContent =
`${prefix}${value}${suffix}`;
}
});
});
// =========================
// PAGE LOAD COUNTER
// Attribute:
// counter-page-load
//
// Example:
// counter-page-load="100+"
// counter-page-load="98%"
// counter-page-load="1.9K+"
// =========================
setTimeout(() => {
document.querySelectorAll("[counter-page-load]").forEach(counter => {
const targetText =
counter.getAttribute("counter-page-load");
if (!targetText) return;
const match =
targetText.match(/-?\d[\d,]*(\.\d+)?/);
if (!match) return;
const rawNumber = match[0];
const number =
parseFloat(rawNumber.replace(/,/g, ""));
const prefix =
targetText.slice(0, match.index);
const suffix =
targetText.slice(match.index + rawNumber.length);
const decimals =
rawNumber.includes(".")
? rawNumber.split(".")[1].length
: 0;
const obj = {
value: 0
};
gsap.to(obj, {
value: number,
duration: 1,
ease: "power3.out",
snap: {
value: decimals
? Math.pow(10, -decimals)
: 1
},
onUpdate() {
const value = decimals
? obj.value.toFixed(decimals)
: Math.round(obj.value).toLocaleString();
counter.textContent =
`${prefix}${value}${suffix}`;
}
});
});
}, 2000);
// =========================
// ScrollTrigger Refresh
// =========================
setTimeout(() => {
lenis.resize();
ScrollTrigger.refresh();
}, 600);
});
</script>