Echemos un vistazo a un carrusel en el que trabajé donde los elementos se deslizan dentro y fuera de la vista con animaciones CSS. Para que cada elemento se deslice dentro y fuera de la vista, utilicé un cubic-bezier para el animation-timing-function
propiedad, en lugar de utilizar una palabra clave de aceleración estándar.
Vea el carrusel de bolígrafos con curva de relajación invertida de Michelle Barker (@michellebarker) en CodePen.
Un bézier cúbico puede parecer confuso a primera vista, pero cuando se usa correctamente, puede agregar un toque agradable a la experiencia del usuario.
Mientras construía este carrusel, me di cuenta de que no solo necesitaba una curva de animación personalizada, sino que también tenía que usarla a la inversa para obtener el efecto correcto. Pensé que valía la pena compartir lo que aprendí porque crear una curva personalizada y revertirla puede parecer complicado, pero en realidad es bastante sencillo.
Primero, una introducción a la relajación
Facilitar es la palabra que se usa para describir la aceleración y desaceleración del progreso de una animación a lo largo de una línea de tiempo. Podemos trazar esto como un gráfico, donde X es hora y y es el progreso de la animación. El gráfico de una animación lineal, que no tiene aceleración ni desaceleración (se mueve a la misma velocidad en todo su recorrido), es una línea recta:
El suavizado no lineal es lo que le da a las animaciones una sensación más natural y realista. Podemos aplicar suavizado a las transiciones y animaciones en CSS. El animation-timing-function
La propiedad nos permite definir el suavizado de una animación. (Las mismas opciones están disponibles para transition-timing-function
.) Tenemos cuatro palabras clave para elegir:
linear
– como se describió anteriormenteease-in
– la animación comienza lento y se acelera a medida que avanzaease-out
– la animación comienza rápido y desacelera hacia el finalease-in-out
– la animación comienza lentamente, se acelera en el medio y se ralentiza hacia el finalease
– el valor predeterminado, una variante deease-in-out
Conociendo cubic-bezier
Si ninguna de esas opciones se adapta a nuestra animación, podemos crear una curva de aceleración personalizada utilizando el cubic-bezier
función. He aquí un ejemplo:
.my-element {
animation-name: slide;
animation-duration: 3s;
animation-timing-function: cubic-bezier(0.45, 0.25, 0.60, 0.95);
}
Si lo preferimos, podemos escribir estas propiedades de forma abreviada, así:
.my-element {
animation: slide 3s cubic-bezier(0.45, 0.25, 0.60, 0.95);
}
Notarás el cubic-bezier
La función toma cuatro valores. Estos son los dos pares de coordenadas necesarios para trazar nuestra curva en el gráfico. ¿Qué representan esas coordenadas? Bueno, si ha utilizado programas de ilustración vectorial, como Illustrator, la idea de puntos vectoriales y “manejadores” que controlan el tamaño y la dirección de la curva puede resultarle familiar. Esto es esencialmente lo que estamos trazando con una curva bézier cúbica.
No necesitamos saber todas las matemáticas detrás de las curvas cúbicas-bezier para crear una animación agradable. Afortunadamente, existen muchas herramientas en línea, como cubic-bezier.com de Lea Verou, que nos permiten visualizar una curva de aceleración y copiar los valores. Esto es lo que hice para la curva de relajación anterior, que se ve así:
Aquí, podemos ver los dos puntos que necesitamos trazar, donde la función cubic-bezier es cubic-bezier(x1, y1, x2, y2)
.
Aplicar suavizado en dos direcciones
Mi carrusel gira en ambas direcciones: si hace clic en la flecha izquierda, el elemento actual se desliza fuera de la vista hacia la derecha y el elemento siguiente se desliza hacia adentro desde la izquierda; y si hace clic en la flecha derecha, ocurre lo contrario. Para que los elementos se deslicen dentro o fuera de la vista, se agrega una clase a cada elemento, dependiendo de si el usuario ha hecho clic en el botón “siguiente” o “anterior”. Mi suposición inicial fue que simplemente podría revertir el animation-direction
para elementos que se deslizan en la dirección opuesta, como este:
.my-element--reversed {
animation: slide 3s cubic-bezier(0.45, 0.25, 0.60, 0.95) reverse;
}
Solo hay un problema: ¡invertir la animación también invirtió la curva de relajación! Entonces, ahora mi animación se ve muy bien en una dirección, pero está completamente desviada en la otra dirección. ¡Oh, no!
En esta demostración, el primer cuadro muestra la animación inicial (un elemento que se desliza de izquierda a derecha) y el segundo cuadro muestra lo que sucede cuando animation-direction
está alreves.
Vea la animación Pen Reverse de Michelle Barker (@michellebarker) en CodePen.
Puede ver que las dos animaciones no tienen la misma sensación en absoluto. El primer cuadro se acelera al principio y se ralentiza suavemente a medida que avanza, mientras que el segundo cuadro comienza bastante lento, luego gana una ráfaga de velocidad antes de desacelerar abruptamente. Esto no se sentiría nada bien para un carrusel.
Tenemos la posibilidad de elegir entre dos opciones para lograrlo:
- Podríamos crear una nueva animación de fotogramas clave para animar los elementos y luego aplicar la misma suavización que antes. Eso no es demasiado difícil en este ejemplo, pero ¿y si tenemos una animación más compleja? Se necesitaría un poco más de trabajo para crear la misma animación al revés, y fácilmente podríamos cometer un error.
- Podríamos usar la misma animación de fotogramas clave (con la
animation-direction: reverse
) e invertir la curva de flexibilización para que obtengamos la misma flexibilización en ambas direcciones. Esto tampoco es muy difícil de hacer.
Para invertir la curva de aceleración de nuestra animación invertida, necesitamos rotar la curva 180 grados sobre su eje y encontrar las nuevas coordenadas.
Podemos hacer esto con algunas matemáticas simples, cambiando los pares de coordenadas y restando cada valor de 1.
Para visualizar esto, imagine que nuestros valores originales son:
x1, y1, x2, y2
Nuestros valores invertidos serán:
(1 - x2), (1 - y2), (1 - x1), (1 - y1)
En esta demostración, el tercer cuadro muestra lo que queremos que suceda: el elemento se desliza en la dirección opuesta, pero con la flexión invertida para darle la misma sensación.
Consulte las Variables CSS de Pen para revertir la aceleración por Michelle Barker (@michellebarker) en CodePen.
Veamos cómo podemos calcular la curva de relajación inversa.
Calcular la nueva curva con variables CSS
¡Podemos usar variables CSS para calcular la nueva curva por nosotros! Asignemos cada valor a una variable:
:root {
--x1: 0.45;
--y1: 0.25;
--x2: 0.6;
--y2: 0.95;
--originalCurve: cubic-bezier(var(--x1), var(--y1), var(--x2), var(--y2));
}
Entonces podemos usar esas variables para calcular los nuevos valores:
:root {
--reversedCurve: cubic-bezier(calc(1 - var(--x2)), calc(1 - var(--y2)), calc(1 - var(--x1)), calc(1 - var(--y1)));
}
Ahora, si hacemos algún cambio en el primer conjunto de variables, la curva invertida se calculará automáticamente. Para que esto sea un poco más fácil de escanear al examinar y depurar nuestro código, me gusta dividir estos nuevos valores en sus propias variables:
:root {
/* Original values */
--x1: 0.45;
--y1: 0.25;
--x2: 0.6;
--y2: 0.95;
--originalCurve: cubic-bezier(var(--x1), var(--y1), var(--x2), var(--y2));
/* Reversed values */
--x1-r: calc(1 - var(--x2));
--y1-r: calc(1 - var(--y2));
--x2-r: calc(1 - var(--x1));
--y2-r: calc(1 - var(--y1));
--reversedCurve: cubic-bezier(var(--x1-r), var(--y1-r), var(--x2-r), var(--y2-r));
}
Ahora todo lo que queda es aplicar la nueva curva a nuestra animación invertida:
.my-element--reversed {
animation: slide 3s var(--reversedCurve) reverse;
}
Para ayudar a visualizar esto, he creado una pequeña herramienta para calcular los valores invertidos de un bézier cúbico. Ingrese los valores de las coordenadas originales para obtener la curva invertida:
Vea el Pen Reverse cubic-bezier de Michelle Barker (@michellebarker) en CodePen.