<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>
<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>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script>
const texts = ["Development.", "Branding.", "Marketing.", "Creative."];
let index = 0;
const el = document.querySelector(".replace-text");
gsap.set(el, { y: 0 });
function changeText() {
gsap.to(el, {
y: -50,
duration: 0.35,
ease: "power2.inOut",
onComplete: () => {
// instantly change text (no split, no fade)
el.textContent = texts[index];
index = (index + 1) % texts.length;
// reset position instantly below
gsap.set(el, { y: 50 });
// come back smoothly
gsap.to(el, {
y: 0,
duration: 0.6,
ease: "back.out(1.6)"
});
}
});
}
changeText();
setInterval(changeText, 2500);
</script>