How I make websites feel premium with motion (GSAP)
The small animation details that make a site feel expensive: text reveals, scroll-driven effects and magnetic buttons, with the GSAP code I use and the rules that keep it fast.
Two websites can have the same layout, the same colours and the same content, and one still feels far more premium. The difference is usually motion: how text arrives, how sections respond to scrolling, how buttons react under your cursor. Here's how I add that feeling with GSAP, without making the site slow or distracting.
Rule one: motion should guide, not decorate
Every animation should answer a question: where should the visitor look, what just changed, what can they click? If an animation doesn't help with one of those, I cut it.
1. Text that reveals line by line
A heading that slides up from behind a mask feels confident and editorial. Wrap each line in a container with overflow: hidden, then animate the inner line up:
gsap.from(".title .line > span", {
yPercent: 110,
duration: 1.1,
ease: "expo.out",
stagger: 0.08,
scrollTrigger: { trigger: ".title", start: "top 85%" }
});
2. Scroll-driven sections
With ScrollTrigger, an animation can follow the scrollbar instead of playing on its own. I use this for progress lines, timelines and image reveals, so the page feels connected to the visitor's hand.
gsap.to(".timeline__fill", {
scaleY: 1,
ease: "none",
scrollTrigger: {
trigger: ".timeline",
start: "top 60%",
end: "bottom 60%",
scrub: 0.6
}
});
3. Magnetic buttons
A call-to-action that leans gently toward the cursor invites a click. It's a tiny detail people notice without knowing why.
const btn = document.querySelector(".btn");
const x = gsap.quickTo(btn, "x", { duration: 0.4, ease: "power3" });
const y = gsap.quickTo(btn, "y", { duration: 0.4, ease: "power3" });
btn.addEventListener("pointermove", (e) => {
const r = btn.getBoundingClientRect();
x((e.clientX - r.left - r.width / 2) * 0.3);
y((e.clientY - r.top - r.height / 2) * 0.3);
});
btn.addEventListener("pointerleave", () => { x(0); y(0); });
4. Smooth scrolling, used carefully
I pair GSAP with Lenis for smooth scrolling on desktop, which makes scroll-driven effects feel fluid. On touch devices I leave native scrolling alone, because people expect their phone to scroll the way it always does.
The rules that keep it fast
- Animate only
transformandopacity. They're cheap for the browser. Animating width, height or top causes layout work and jank. - Respect reduced motion. If a visitor has turned on "reduce motion" in their system settings, I show everything instantly.
- Keep it short. Most UI motion lands between 0.3 and 1.2 seconds. Anything longer starts to feel slow.
- Use one easing family. Mixing many curves makes a site feel inconsistent. I mostly use
expo.out. - Never hide content behind animation. If JavaScript fails, the page should still be readable.
Good motion is felt, not noticed.
Every animation on this portfolio is built this way, from the hero to the scroll-filled timeline. If you'd like your website to feel this polished, let's talk about your project.
Need this for your website?Tell me about your project and get a fixed quote, usually within 24 hours.