Bazele animației
Principiile unei animații bune, progres → easing → interpolare, ce unealtă alegi, baza minimă.
Actualizat
Ce face o animație bună
O animație bună explică: de unde a venit un element, unde a plecat, ce s-a schimbat, că acțiunea ta a avut efect. Una proastă doar întârzie userul. Înainte de unelte, 5 idei care fac diferența între „merge” și „arată profesionist”:
| Principiu | Ce înseamnă | Exemplu |
|---|---|---|
| durată scurtă | 150–300 ms pentru UI, rar peste 500 ms | un dropdown care apare în 200 ms |
| easing | nimic real nu se mișcă liniar | ease-out la apariție |
| stagger | elementele unei liste pornesc decalat, nu toate odată | carduri care apar unul după altul, la 60 ms |
| distanță mică | mișcări de 8–24 px, nu de-a lungul ecranului | y: 16 → 0 + opacity: 0 → 1 |
| continuitate | elementul se transformă, nu dispare și reapare | un card care se extinde în pagina de detaliu |
Și regula tehnică: animă transform și opacity — vezi Tranziții și animații în CSS.
Cele 3 numere din spatele oricărei animații
Orice librărie, sub capotă, face același calcul la fiecare cadru (~60 pe secundă):
- progres
tde la 0 la 1 = timp scurs / durată; - easing: transformă
tîntr-un progres „simțit” —easeOutCubic(t) = 1 - (1 - t)³; - interpolare (lerp): valoarea curentă =
start + (end - start) × progres.
const lerp = (a, b, t) => a + (b - a) * t
const easeOutCubic = t => 1 - (1 - t) ** 3
lerp(0, 100, easeOutCubic(0.5)) // 87.5 — la jumătatea timpului, deja aproape de finalSpring-urile (Motion) nu au durată fixă: simulează un arc cu rigiditate și amortizare — de aceea par naturale și se pot întrerupe fără salt.
Uneltele — care și când
| Unealtă | Pentru | Mărime | Când |
|---|---|---|---|
| CSS (transition, @keyframes) | hover, focus, apariții simple | 0 KB | mereu întâi |
| View Transitions API | tranziții între stări / pagini | 0 KB | morph între liste și detalii |
Motion (motion/react) |
animații declarative în React: apariție, ieșire, layout, gesturi, scroll | mediu | implicit în React |
| GSAP | timeline-uri complexe, scroll storytelling, text animat, SVG | mediu | landing-uri, site-uri de prezentare |
| Lottie | animații desenate în After Effects | variabil | ilustrații animate |
| Three.js / R3F | 3D, WebGL | mare | experiențe 3D |
Cea mai scurtă bază ca să începi
Trei rețete acoperă 80% din ce vezi pe site-urile „care arată bine”:
1. Apariție la scroll (doar CSS, fără JS):
.reveal {
animation: reveal linear both;
animation-timeline: view();
animation-range: entry 0% entry 60%;
}
@keyframes reveal {
from { opacity: 0; transform: translateY(24px); }
}2. Listă care intră cu stagger (Motion):
<motion.ul initial="hidden" animate="show" variants={{ show: { transition: { delayChildren: stagger(0.06) } } }}>
{items.map(item => (
<motion.li key={item.id} variants={{ hidden: { opacity: 0, y: 16 }, show: { opacity: 1, y: 0 } }} />
))}
</motion.ul>3. Feedback la interacțiune (Motion):
<motion.button whileHover={{ scale: 1.03 }} whileTap={{ scale: 0.97 }}>Salvează</motion.button>Detalii în lecțiile Motion și GSAP; exemple complete în Exemple interesante.
Accesibilitate
Respectă prefers-reduced-motion — în CSS cu media query, în Motion cu useReducedMotion() sau <MotionConfig reducedMotion="user">, în GSAP cu gsap.matchMedia(). Nu anima lucruri care clipesc de mai mult de 3 ori pe secundă.
Pe scurt
- Scurt (150–300 ms),
ease-out, stagger, distanțe mici, doartransformșiopacity. - Orice animație = progres → easing → interpolare.
- CSS întâi; Motion pentru React; GSAP pentru timeline-uri și scroll complex; respectă reduced motion.