Elegir el ease por lo que comunica
Un criterio de decisión basado en qué información transmite el movimiento: causalidad, peso, jerarquía y estado, en lugar de en cuál queda más bonito.
Después de tres lecciones de catálogo llega la pregunta que importa: cómo se elige. La respuesta que circula —“prueba y usa el que quede mejor”— no es una respuesta, porque “mejor” no es un criterio y porque no escala a un equipo ni a un sistema de diseño. Un ease es un canal de información: comunica de dónde viene una fuerza, cuánto pesa un objeto, qué es importante y en qué estado está el sistema. Elegirlo es decidir qué quieres decir, y eso sí es una pregunta con respuesta.
- Formular la elección de un ease como una decisión sobre qué comunica el movimiento.
- Aplicar los cuatro criterios —causalidad, peso, jerarquía y estado— a casos concretos.
- Reconocer los tres errores de easing que estropean interfaces por lo demás correctas.
- Reducir el catálogo a un conjunto pequeño y defendible para un proyecto.
Criterio uno: causalidad
Lo primero que comunica un ease es de dónde viene la energía. Una curva out dice “algo empujó esto al principio y ahora se está posando”; una in dice “esto está cogiendo velocidad hacia algo”.
De ahí sale la regla de la relación con el gesto del usuario. Si la animación es consecuencia directa de una acción del usuario —un clic, un arrastre, una tecla— la energía viene del usuario y llegó al principio: le corresponde un out. Si la animación anticipa algo o va hacia un destino que el usuario aún no ve, la energía se acumula: le corresponde un in.
El error clásico es el modal que se cierra con out. El usuario pulsa cerrar, y el modal sale disparado inmediatamente y frena antes de desaparecer: la lectura es que el modal huyó por su cuenta. Con in, el modal empieza a irse despacio y acelera al salir: la lectura es que se fue porque tú lo mandaste. Es literalmente la misma animación con la curva del revés y comunica cosas opuestas.
// El usuario abre: la energia llego con el clic.
gsap.from('.modal', { y: 30, autoAlpha: 0, duration: 0.4, ease: 'power2.out' });
// El usuario cierra: el modal se marcha.
gsap.to('.modal', { y: 20, autoAlpha: 0, duration: 0.28, ease: 'power2.in' });
Un caso especial: cuando la animación no la ha provocado el usuario —una notificación que llega, una actualización de datos— el out sigue siendo correcto pero conviene suavizarlo, porque un arranque agresivo sin causa visible se lee como un sobresalto. Ahí sine.out o power1.out funcionan mejor que power4.out.
Criterio dos: peso
El segundo canal es la masa aparente. Y aquí hay una relación que se puede enunciar como regla: la agresividad de la curva y el tamaño del objeto van juntos, pero la duración y el tamaño también.
Un objeto grande con una curva plana se ve torpe. Un objeto grande con una curva pronunciada y una duración corta se ve sin masa. Lo que produce la sensación de peso es la combinación de curva pronunciada con duración generosa: mucha aceleración inicial y una cola larga en la que el objeto se asienta.
| Elemento | Ease | Duración orientativa |
|---|---|---|
| Icono, tooltip, indicador | power1.out o sine.out |
120 a 200 ms |
| Botón, tarjeta, elemento de lista | power2.out |
200 a 350 ms |
| Panel lateral, hoja modal | power3.out |
350 a 500 ms |
| Sección completa, cambio de vista | power3.inOut o power4.inOut |
500 a 800 ms |
Esa tabla no es una ley; es un punto de partida calibrado que funciona y del que se sale conscientemente. Lo que sí es una regla: la duración crece con el tamaño y con la distancia, y si alguna vez tienes que elegir entre ajustar el ease y ajustar la duración para que algo “se sienta más pesado”, ajusta la duración primero.
Criterios tres y cuatro: jerarquía y estado
Jerarquía
El tercer canal es la importancia relativa, y funciona por contraste. Si todo en la interfaz usa power2.out, nada destaca; el ease deja de comunicar porque no hay variación. Una curva distinta llama la atención exactamente en la medida en que se diferencia del resto.
De ahí la disciplina que más rinde: un ease por defecto para el 90% y dos o tres excepciones con significado. El por defecto se establece una vez y no se piensa más:
gsap.defaults({ ease: 'power2.out', duration: 0.4 });
Y las excepciones se reservan para momentos que de verdad lo son. Un back.out en la confirmación de que algo se ha guardado. Un elastic.out en el elemento que el usuario acaba de crear. Un steps en el contador que sube. Tres excepciones en toda una aplicación se leen como intención; treinta se leen como ruido.
El corolario incómodo: los eases llamativos que tanto apetece usar —elastic, bounce, back con sobrepasos altos— son caros en atención y hay que gastarlos como se gasta el color de acento. Una interfaz donde todo rebota no transmite alegría: transmite que nadie decidió nada.
Estado
El cuarto canal es la naturaleza del cambio. Hay tres tipos y cada uno pide una cosa distinta.
Un cambio discreto —de un estado a otro, sin continuo entre medias— pide steps o algo que se le parezca. Un contador que pasa de 3 a 4 no debería mostrar 3,7 en ningún momento. La animación existe para que el usuario perciba que hubo un cambio, no para mostrar los valores intermedios.
Un cambio continuo y acotado —una barra de progreso, un deslizante— pide una curva suave y a menudo simplemente none. Aquí los valores intermedios son información real y distorsionarlos es mentir: una barra de progreso con power4.out dice que el proceso va rapidísimo y luego se atasca, aunque el proceso vaya a ritmo constante.
Un cambio de posición o presencia —lo que hemos estado viendo— pide las curvas de siempre, porque ahí los valores intermedios no son información sino narración.
// Progreso real: no mientas sobre el ritmo.
gsap.to('.barra', { scaleX: fraccion, duration: 0.3, ease: 'none' });
// Contador discreto.
gsap.to(estado, {
valor: 42,
duration: 1,
ease: 'steps(42)',
onUpdate: () => (salida.textContent = Math.round(estado.valor)),
});
Los tres errores que estropean interfaces correctas
El inOut en todo. Es el error más común y el más difícil de ver, porque inOut nunca se siente mal: se siente correcto y anodino. El problema es que un inOut en algo que entra desperdicia el arranque —el momento en el que el usuario está mirando— en una aceleración lenta. Reserva inOut para movimientos que empiezan y acaban dentro de la pantalla.
El ease agresivo con duración larga. Un power4.out de 900 milisegundos es una animación de 300 milisegundos seguida de 600 de nada, durante los cuales el elemento sigue formalmente ocupado, los callbacks no se han disparado y una interacción del usuario tiene que esperar o interrumpir. Si vas a usar exponentes altos, acorta.
El ease elegido antes que la duración. El orden correcto de ajuste es: primero la duración, que es lo que determina si algo se siente rápido o lento; después la variante in, out o inOut, que es lo que determina la causalidad; y solo al final el exponente, que es un ajuste fino. Empezar por el exponente es afinar antes de haber decidido la nota.
Existe una prueba que resuelve la mayoría de las discusiones sobre easing y que casi nadie hace: enseña la interfaz a alguien que no la haya visto, pídele que haga una tarea, y al terminar pregúntale qué se movía. Si te describe las animaciones, has fallado. Si te describe la tarea, has acertado.
El motivo es que la animación de interfaz no es la animación de un anuncio. Su función es reducir la carga cognitiva explicando de dónde vino algo y a dónde fue, no producir una impresión estética. Una curva que se nota está gastando atención que el usuario necesitaba para otra cosa, y el coste no aparece en ninguna métrica hasta que aparece en el ratio de finalización de tareas.
Y de ahí sale el criterio que uso para saber si un ease está sobreajustado: si la diferencia entre dos candidatos solo se aprecia poniéndolos uno al lado del otro a cámara lenta, la diferencia no existe para el usuario y estás gastando tiempo en una decisión sin consecuencias. Elige el más simple de los dos, escríbelo en el defaults, y dedica ese tiempo a la duración, que sí se nota.
Audita una interfaz tuya: lista todas las animaciones con su ease y su duración, y clasifica cada una según los cuatro criterios. Cuenta cuántos eases distintos hay. Si son más de cinco, reduce el conjunto: establece uno por defecto con gsap.defaults, deja dos excepciones justificadas, y comprueba que la interfaz no ha perdido nada. Casi siempre gana claridad.