Vai al contenuto principale
kineon carousel

Animazioni multi-layer e interazioni avanzate con GSAP: il caso Kineon

29 mag 2026·4 min di lettura
GSAPTypescriptTailwind CSSmulti-layer animationmouse tracking 3Dtab switcher animation

Il progetto Kineon è nato da un brief chiaro: un sito single-page ad alto impatto visivo per un'azienda competitiva nel settore dell'automazione industriale. Next.js 16, React 19, Tailwind CSS v4 e GSAP 3.15 sono stati gli strumenti. Nessun template, tutto custom su design di Alice Proglio. Le animazioni non dovevano essere decorative, ma funzionali: comunicare precisione e creare percezione di premium quality attraverso il movimento.

Parallasse 3D dell'Hero con tracking del mouse

L'hero presenta un braccio robotico statico. Il rischio? Sembrare piatto e privo di vita. La soluzione è stato un sistema multi-layer con tre profondità indipendenti, ognuna con velocità e timing diversi, animate con gsap.quickTo per massima fluidità senza jank.

Il glow spotlight (layer 1) segue il cursore con duration 1.2s e ease power2.out, simulando una sorgente luminosa che si muove con l'utente. Il braccio robotico (layer 2) combina traslazione X/Y a duration 0.6s con rotazione 3D (rotationX/Y) a duration 0.7s e transformPerspective 600. Questa dissociazione tra timing di traslazione e rotazione è deliberata: crea un'inerzia percepita che rende il movimento più organico e meno meccanico.

Il terzo layer (testo e contenuto) si muove nella direzione opposta al cursore: quando sposti il mouse a destra, il testo si muove a sinistra. Questo dettaglio è cruciale. Il movimento contrario amplifica la percezione di profondità: il testo appare come un layer "più lontano" rispetto al braccio, senza ricorrere a CSS 3D esplicito che rallenterebbe il rendering.

hero-animation.ts
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" });
};
Hero Kineon

Pill tab switcher: quando il UI diventa oggetto

La sezione prodotti ha un tab switcher Machines / Robots. L'approccio CSS tradizionale (background che appare/scompare) è abrupato e visivamente statico. La soluzione è stata una pill assolutamente posizionata che scorre fisicamente da una tab all'altra, creando la percezione di un oggetto unico che si sposta.

Implementazione: getBoundingClientRect() su tab trigger e container list per calcolare la posizione relativa della pill. La pill parte da left:0 width:0, viene posizionata al mount con gsap.set() istantaneo (senza animazione) per evitare un "volo" iniziale. Al cambio tab, gsap.to() con ease back.out(1) e duration 0.55s. L'ease back.out aggiunge un leggero overshooting: la pill "atterra" con inerzia, come un oggetto fisico.

pill-switcher.tsx
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);
};

// Nel JSX, la tab attiva ha data-[state=active]:bg-transparent
// per rimuovere il background nativo e evitare due sfondi sovrapposti.

Dropdown mobile: timing sincronizzato e z-index discipline

Il menu mobile è stato riprogettato come tendina full-screen che scende dall'header. GSAP anima height da 0 a window.innerHeight - navbarHeight. Il valore target è calcolato runtime per gestire correttamente breakpoint diversi (navbar h-16 su mobile, h-24 su md).

Due dettagli critici: primo, il backdrop-blur dell'header si estende sulla tendina perché un div absolute inset-0 sul parent fixed copre tutto, quindi non serve duplicarlo. Secondo, un div relative z-10 sul dropdown garantisce che i link stiano sopra il layer blur — bug risolto: gli elementi absolute si dipingono sopra i figli in-flow nello stesso stacking context senza z-index esplicito.

Kineon è diventato un case study su come GSAP non sia uno strumento "per fare animazioni belle", ma un framework preciso di timing, easing e tracking del movimento. Ogni animazione risolve un problema specifico di UX: profondità percepita sull'hero, feedback visivo sul tab switcher, transizioni fluide sul mobile. Il risultato è un sito che comunica tecnologia e affidabilità non solo con il contenuto, ma con il modo in cui il contenuto si muove.

Articoli correlati

Ask Fabio