
Multi-layer animations and advanced interactions with GSAP: the Kineon case
The Kineon project originated from a clear brief: a single-page high-impact site for a competitive player in industrial automation. Next.js 16, React 19, Tailwind CSS v4, and GSAP 3.15 were the tools. No template, everything custom built on Alice Proglio's design. Animations were not meant to be decorative, but functional: to communicate precision and create a perception of premium quality through movement.
3D parallax hero with mouse tracking
The hero features a static robotic arm. The risk? Looking flat and lifeless. The solution was a multi-layer system with three independent depths, each with different speeds and timings, animated with gsap.quickTo for maximum fluidity without jank.
The glow spotlight (layer 1) follows the cursor with duration 1.2s and ease power2.out, simulating a light source that moves with the user. The robotic arm (layer 2) combines X/Y translation at duration 0.6s with 3D rotation (rotationX/Y) at duration 0.7s and transformPerspective 600. This dissociation between translation and rotation timing is deliberate: it creates perceived inertia that makes the movement more organic and less mechanical.
The third layer (text and content) moves in the opposite direction to the cursor: when you move the mouse right, the text moves left. This detail is crucial. The opposite movement amplifies the perception of depth: the text appears as a layer "further away" from the arm, without resorting to explicit CSS 3D that would slow down rendering.
const handleMouseMove = (e: MouseEvent) => {
const x = e.clientX - window.innerWidth / 2;
const y = e.clientY - window.innerHeight / 2;
glowRef.current && gsap.quickTo(glowRef.current, { x: x * 0.3, y: y * 0.3 }, { duration: 1.2, ease: "power2.out" })();
armRef.current && gsap.quickTo(armRef.current, { x: x * 0.15, y: y * 0.15, rotationX: y * 0.05, rotationY: x * 0.05 }, { duration: 0.6 })();
textRef.current && gsap.quickTo(textRef.current, { x: -x * 0.1, y: -y * 0.1 }, { duration: 0.9 })();
};
const handleMouseLeave = () => {
gsap.to([glowRef.current, armRef.current, textRef.current], { x: 0, y: 0, rotationX: 0, rotationY: 0, duration: 0.8, ease: "power2.inOut" });
};Pill tab switcher: when UI becomes an object
The products section has a Machines / Robots tab switcher. The traditional CSS approach (background appearing/disappearing) is abrupt and visually static. The solution was an absolutely positioned pill that physically slides from one tab to another, creating the perception of a single object moving.
Implementation: getBoundingClientRect() on tab triggers and container list to calculate the pill's relative position. The pill starts at left:0 width:0, positioned at mount with instant gsap.set() (no animation) to avoid an initial "flight". On tab change, gsap.to() with ease back.out(1) and duration 0.55s. The back.out ease adds slight overshooting: the pill "lands" with inertia, like a physical object.
const handleTabChange = (value: string) => {
const trigger = document.querySelector(`[data-tab-trigger="${value}"]`);
const list = containerRef.current;
if (!trigger || !list) return;
const triggerRect = trigger.getBoundingClientRect();
const listRect = list.getBoundingClientRect();
const x = triggerRect.left - listRect.left;
gsap.to(pillRef.current, {
x,
width: triggerRect.width,
duration: 0.55,
ease: "back.out(1)"
});
setActiveTab(value);
};
// In JSX, the active tab has data-[state=active]:bg-transparent
// to remove the native background and avoid two overlapping backgrounds.Mobile dropdown: synchronized timing and z-index discipline
The mobile menu was redesigned as a full-screen curtain that drops from the header. GSAP animates height from 0 to window.innerHeight - navbarHeight. The target value is calculated at runtime to properly handle different breakpoints (navbar h-16 on mobile, h-24 on md).
Two critical details: first, the header's backdrop-blur extends over the dropdown because an absolute inset-0 div on the fixed parent covers everything, so no need to duplicate it. Second, a relative z-10 div on the dropdown ensures links stay above the blur layer — bug fixed: absolutely positioned elements paint above in-flow children in the same stacking context without explicit z-index.
Kineon became a case study in how GSAP is not a tool "for making pretty animations", but a precise framework for timing, easing, and movement tracking. Every animation solves a specific UX problem: perceived depth on the hero, visual feedback on the tab switcher, smooth transitions on mobile. The result is a site that communicates technology and reliability not just through content, but through the way content moves.


