Timing delle animazioni e percezione UX
1) Perché il timing è critico
L'animazione non è un gioiello, ma una manipolazione del tempo di percezione. I millisecondi influenzano:- Senso di risposta immediata e fiducia nel sistema
- chiarezza delle cause e delle relazioni investigative (da dove/dove è stato spostato l'elemento);
- stanchezza e comfort in lunghe sessioni;
- precisione delle azioni (soprattutto su mobile e tassi elevati).
Regola: il timing serve al significato. Se l'animazione non aiuta a capire cos'è successo, è un ostacolo.
2) Psicofisica e soglie
Punti di riferimento per il prodotto UI:- ≤ 50 ms - eco di input (stampa, effetto click) Sembra istantaneo.
- 100 ms è il primo Fidbeck visivo per azione (il pulsante ha beneficiato).
- 120-180 ms - hover/focus, transizione di stato «morbida».
- 180-280 ms - modali/pannelli Si vede come un'apparizione naturale.
- 300-500 ms - spostamento attento (shared element), progresso «passo in avanti».
- ≈ 1200-1600 ms - ciclo skeleton/shimmer; Più lungo, più stanco.
3) Curve di accelerazione (easing) e peso
L'elemento «peso» partirà più velocemente e «incollato» alla fine. Curve di base:- Standard: 'cubic-bezier (0. 2, 0, 0. 2, 1) 'è un altoparlante neutrale «materiale».
- Accelerazione (pressed): 'cubic-bezier (0. 4, 0, 1, 1) '- ingresso veloce, clic breve.
- Rallentamento (overlay out): 'cubic-bezier (0, 0, 0. 2, 1) 'è un'uscita morbida.
- Accento sottolineato (raramente): 'cubic-bezier (0. 2, 0. 8, 0. 2, 1. 2)` с overshoot ≤ 8 px.
Ottica di peso: più grande è il componente (scheda, drower), più lunga è la durata (+ 40-80 ms a base).
4) Fasi e coreografie
Dividere il movimento in fasi:1. Iniziazione (10-40 ms): facile fade/scale 0. Il segnale d'inizio è 98→1.
2. Trasporto (fase principale) - Spostamento/espansione.
3. Sedimento (20-60 ms) - leggero freno, stabilizzazione ombra/anello fuoco.
Cascata (stagger):- Elenchi: 20-40 ms/elemento, massimo 6-8 elementi consecutivi.
- Moduli senza cascata; tutto appare contemporaneamente per non interferire con l'immissione.
«Indietro» si specchia «avanti» e più veloce del 15-30%.
5) Timing per tipo di interazione
6) Percezione del tempo: come «accelerare» senza accelerazione reale
Instant afordance: cambio istantaneo cursors/pressed stile di 100 ms prima della rete.
Nascondi la complessità: parallelo di caricamento trascinamento dei dati in background fino all'apertura del pannello.
Ancoraggio di senso: shared element e direzione di movimento riducono il costo cognitivo di attesa.
Aggiornamenti ottimistici: UI «pronto» subito, il server conferma o ritira.
7) Stanchezza e igiene delle animazioni
Evitare pulsazioni infinite; qualsiasi ciclo deve essere intermittente o disattivato.
Fate senza blur/box-shadow su ogni nodo.
Supporta «preferers-reduced-motion: reduce»: lascia solo fade da 100 ms o un interruttore di stato statico.
css
@media (prefers-reduced-motion: reduce) {
{ animation: none! important; transition-duration:.01ms! important; }
}
8) Token timing (sistema di progettazione)
json
{
"motion": {
"duration": { "press": 90, "hover": 160, "focus": 160, "overlayIn": 240, "overlayOut": 180, "tab": 200, "shared": 280 },
"easing": {
"standard": "cubic-bezier(0. 2,0,0. 2,1)",
"accelerate": "cubic-bezier(0. 4,0,1,1)",
"decelerate": "cubic-bezier(0,0,0. 2,1)"
},
"stagger": { "listItem": 30, "maxItems": 8 }
}
}
La denominazione è motion. duration.{role}` и `motion. easing. {role} ', un unico componente per il motore e il Figma.
9) Implementazione: CSS e Framer Motion
Preset CSS:css
:root{
--dur-press:90ms; --dur-hover:160ms; --dur-overlay-in:240ms; --dur-overlay-out:180ms;
--ease-std:cubic-bezier(.2,0,.2,1);
--ease-acc:cubic-bezier(.4,0,1,1);
--ease-dec:cubic-bezier(0,0,.2,1);
}
.button{ transition: transform var(--dur-press) var(--ease-acc), box-shadow var(--dur-hover) var(--ease-std); }
.button:active{ transform: scale(.98); }
.modal-enter{ animation: modalIn var(--dur-overlay-in) var(--ease-std) both; }
.modal-exit { animation: modalOut var(--dur-overlay-out) var(--ease-dec) both; }
@keyframes modalIn{ from{opacity:0; transform:translateY(16px) scale(.98)} to{opacity:1; transform:none} }
@keyframes modalOut{ from{opacity:1} to{opacity:0; transform:translateY(8px) scale(.99)} }
Framer Motion:
tsx import { motion, AnimatePresence } from "framer-motion";
export function Modal({ open, children }) {
return (
<AnimatePresence>
{open && (
<motion. div initial={{opacity:0}} animate={{opacity:1}} exit={{opacity:0}}
transition={{duration:.18, ease:[0. 2,0,0. 2,1]}} className="fixed inset-0 bg-black/50">
<motion. div initial={{y:16, scale:.98, opacity:0}}
animate={{y:0, scale:1, opacity:1, transition:{duration:.24, ease:[0. 2,0,0. 2,1]}}}
exit={{y:8, scale:.99, opacity:0, transition:{duration:.18, ease:[0,0,0. 2,1]}}}
className="m-auto max-w-lg rounded-2xl bg-white p-6">
{children}
</motion. div>
</motion. div>
)}
</AnimatePresence>
);
}
10) Composizione del tempo: sequenza vs parallela
Parallelo (fade + translate contemporaneamente) - Più veloce.
La sequenza (prima contenitore, poi contenuto) è più chiara della struttura, ma più lunga. Applicare quando è importante mostrare la gerarchia.
Evitare «scalini»> 60 ms tra gli elementi strettamente collegati in un unico blocco.
11) Timing e contenuti
Testo: non animare letter/word-by-word nei prodotti; È una tecnica di marketing.
Numeri/contatori: passo 40-60 ms con batch, senza tremare layout (tabula-nums).
Grafici: apertura della serie 180-240 mc, hover-highlight 120 mc.
12) Disponibilità e errore di percezione
Gli stili di attivazione devono essere visualizzati senza ritardo.
Avvisi/errori - L'animazione è minima (≤ 120 ms) se l'utente è con AT (assistenziale tech).
Evitare flash> 3/s e grandi punti di contrasto.
13) Specificità del iGaming
Puntata/acquisto:- Press ≤ 100 ms; stato «busy» subito; toast/indicatore finale - senza ritardi.
- Il timing della risposta UI è più importante dell'animazione di conferma: conferma breve 120-160 ms.
- Partenza a 200 ms, ciclo uniforme, frenata 300-500 ms; Non c'è niente di infinito.
- Win-Spin 500 ms, senza ≤; Il testo della somma è AAA.
- Aggiornamenti batch (250-1000 ms) diff visivo di 160 ms; Nessun salto di layout.
- Su hover/focus è il debouns di illuminazione 80-120 ms per non «lampeggiare».
14) Anti-pattern
Curve lineari per spostamenti (sensazione di meccanicità).
Durata> 400 ms per gli stati semplici del pulsante.
Cascata 100 + ms su un elenco di decine di elementi (trazione).
Ombre/blur su centinaia di elementi nell'animazione.
Incoerenza: azioni simili a timing diversi nello stesso prodotto.
Attivazione ritardata o ritardo nell'attivazione della tastiera.
15) QA-foglio di tempo
Consistenza
- Timing e curve vengono prese da token, uguali per le stesse azioni.
Risposta
- Press/hover/focus si inseriscono in una scala di 80-180 ms.
- La prima risposta visiva è 100 ms.
Coreografia
- L'ingresso e l'uscita sono simmetrici; uscita più veloce di 15-30%.
- Cascata non supera 8 elementi e 40 ms passo.
A11y
- 'prefers-reduced-motion'supportato; Attivo senza ritardi.
- Nessun lampeggiante> 3/s
Performance
- Vengono animati solo «transfer/opacity»; Nessun blur/ombra di massa.
16) Documentazione in progettazione
«Motion Tokens»: duration/easing/stagger + mappa delle applicazioni (button, overlay, tav, list).
Rhythm & Phasing: schemi a cascata e reversibilità.
«Reduce Motion», regole di degrado e esempi.
«Do/Don't» - Clip brevi con timecode e metriche di destinazione (INP/First Feedback).
Breve riepilogo
Un buon timing è una risposta immediata, una coreografia comprensibile e curve a basso costo. Tenete una breve durata per i micro-stati, allungate solo dove questo aggiunge senso, mantenete il reduce-motion e non animate le proprietà «costose». Allora l'interfaccia si sente viva e affidabile, soprattutto in scenari in tempo reale e tassi elevati.