Escribir animaciones que dan vida a su sitio | Programar Plus

La animación web es uno de los factores que pueden mejorar considerablemente la apariencia de su sitio web. Lamentablemente, a diferencia de las aplicaciones móviles, no hay tantos sitios web que utilicen la animación para su beneficio como podría pensarse. No queremos contar el suyo entre esos, por lo que este artículo es para usted y cualquier otra persona que busque formas de usar la animación para una mejor experiencia de usuario. Específicamente, vamos a aprender cómo hacer que las interacciones web sean agradables usando animaciones CSS.

Esto es lo que vamos a construir juntos:

Demostración en vivo GitHub Repo

Antes de seguir adelante, vale la pena mencionar que voy a suponer que tiene al menos cierta familiaridad con los marcos front-end modernos y una comprensión básica de las animaciones CSS. Si no lo haces, ¡no temas! Programar Plustiene excelentes guías sobre React y Vue, así como una publicación de almanaque completa sobre CSS animation propiedad.

¿Bien? Bien, hablemos de por qué querríamos usar animación en primer lugar y cubramos información básica sobre animaciones CSS.

¿Por qué animaríamos algo?

Probablemente podríamos hacer una publicación completa solo sobre este tema. ¡Oh espera! Sarah Drasner ya lo hizo y sus puntos son conmovedores y convincentes.

Pero, para resumir las cosas en base a mis propias experiencias:

  • Las animaciones mejoran la forma en que los usuarios interactúan con una interfaz. Por ejemplo, las animaciones inteligentes pueden reducir la carga cognitiva al brindar a los usuarios un mejor contexto entre las transiciones de página.
  • Pueden proporcionar señales claras a los usuarios, como dónde queremos que centren su atención.
  • Las animaciones sirven como otro patrón de diseño en sí mismas, lo que ayuda a los usuarios a vincularse emocionalmente con la interfaz e interactuar con ella.
  • Otro beneficio de usar animaciones es que pueden crear la percepción de que un sitio o aplicación se carga más rápido de lo que realmente lo hace.

Un par de reglas de la casa con animaciones.

¿Alguna vez te has topado con un sitio que anima todas las cosas? Wow, eso puede ser discordante. Entonces, aquí hay un par de cosas que debe evitar cuando trabaje con animaciones para que nuestra aplicación no caiga en el mismo barco:

  • Evite animar propiedades CSS que no sean transform y opacity. Si se deben animar otras propiedades, como ancho o alto, asegúrese de que no se produzcan muchos cambios de diseño al mismo tiempo. En realidad, las animaciones tienen un costo y puede ver exactamente cuánto al consultar los disparadores de CSS.
  • Además, solo porque las animaciones pueden crear ganancias de rendimiento percibidas, en realidad hay un punto de rendimiento decreciente cuando se trata de usarlas. Animar demasiados elementos al mismo tiempo puede resultar en una disminución del rendimiento.

¡Ahora podemos ensuciarnos las manos con algo de código!

Construyamos una aplicación de música

Vamos a crear la aplicación de música que vimos anteriormente, que está inspirada en el tiro Dribbble de Aurélien Salomon. Elegí este ejemplo para que podamos centrarnos en las animaciones, no solo dentro de un componente, sino también entre diferentes rutas. Construiremos esta aplicación usando Vue y crearemos animaciones usando CSS estándar (es decir, sin marco).

Las animaciones deben ir de la mano con el desarrollo de la interfaz de usuario. Es probable que la creación de la interfaz de usuario antes de definir su movimiento cueste mucho más tiempo. En este caso, el tiro de Dribbble nos brinda ese alcance.

Comencemos con el desarrollo.

Paso 1: activa la aplicación localmente

Lo primero es lo primero. Necesitamos configurar un nuevo proyecto Vue. Nuevamente, asumimos una comprensión básica de Vue aquí, así que consulte la guía de aprendizaje de Vue para obtener más información sobre la configuración.

Necesitamos un par de dependencias para nuestro trabajo, en particular vue-router para la transición entre vistas y sass-loader para que podamos escribir en Sass y compilar en CSS. Aquí hay un tutorial detallado sobre el uso de rutas y Sass se puede instalar apuntando la línea de comando al directorio del proyecto y usando npm install -D sass-loader node-sass.

¡Tenemos lo que necesitamos!

Paso 2: Configuración de rutas

Para crear rutas, primero vamos a crear dos componentes mínimos: Artists.vue y Tracks.vue. Soltaremos un nuevo archivo en el src carpeta llamada router.js y agregue rutas para estos componentes como:

import Vue from 'vue'
import Router from 'vue-router'
import Artists from './components/Artists.vue'
import Tracks from './components/Tracks.vue'

Vue.use(Router)
export default new Router({
	mode: 'history',
	routes: [
		{
			path: "https://css-tricks.com/",
			name: 'artists',
			component: Artists
		},
		{
			path: '/:id',
			name: 'tracks',
			component: Tracks
		}
	]
})

Importar router.js en el main.js e inyectarlo en la instancia de Vue. Por último, reemplace el contenido de su App.vue por <router-view/>.

Paso 3: crea los componentes y el contenido para la aplicación de música

Necesitamos dos componentes entre los que haremos la transición con la animación. Esos van a ser:

  1. Artists.vue: una grilla de artistas
  2. Tracks.vue: una imagen de artista con un botón Atrás

Si quiere avanzar un poco, aquí hay algunos activos con los que puede trabajar:

  1. Imágenes y datos de muestra en formato JSON.
  2. Contenido de los componentes

Cuando todo esté dicho y hecho, las dos vistas resultarán en algo como esto:

Artists.vue (izquierda) y Tracks.vue (derecha)

Paso 4: ¡Anima!

Aquí estamos, la parte a la que realmente queríamos llegar todo este tiempo. La animación más importante de la aplicación es la transición de Artistas a Pistas al hacer clic en un artista. Debería sentirse perfecto cuando al hacer clic en la imagen de un artista se enfoca esa imagen mientras se pasa de una vista a la siguiente. Este es exactamente el tipo de animación que rara vez vemos en las aplicaciones, pero que puede reducir drásticamente la carga cognitiva de los usuarios.

Para asegurarnos de que todos estamos en la misma página, nos referiremos a la primera imagen de la secuencia como la imagen “anterior” y a la segunda como la imagen “actual”. Bajar el efecto es relativamente fácil siempre y cuando conozcamos las dimensiones y la posición de la imagen anterior en la transición. Podemos animar la imagen actual transformándola según la imagen anterior.

La fórmula que estoy usando es transform: translate(x, y) scale(n), donde n es igual al tamaño de la imagen anterior dividido por el tamaño de la imagen actual. Note que podemos usar un valor estático de n ya que las dimensiones son fijas para todas las imágenes. Por ejemplo, el tamaño de la imagen en la vista Artistas es 190x190 y 240x240 en la vista Pistas. Así, podemos reemplazar n por 190/240 = 0.791. Eso significa que el valor de transformación se convierte en translate(x, y) scale(0.791) en nuestra ecuación.

Animación de artistas a pistas

Lo siguiente es encontrar x y y. Podemos obtener estos valores a través del evento de clic en la vista Artistas como:

const {x, y} = event.target.getBoundingClientRect()

…y luego envía estos valores a la vista Tracks, todo mientras cambias la ruta. Dado que no estamos utilizando ninguna biblioteca de administración de estado, los dos componentes se comunicarán a través de su componente principal, que es el componente de nivel superior, App.vue. En App.vue, creemos un método que cambie la ruta y envíe la información de la imagen como parámetros.

gotoTracks(position, artistId) {
	this.$router.push({
		name: 'tracks',
		params: {
			id: artistId,
			position: position
		}
	})
}

Aquí está el código relevante del repositorio para referencia, en caso de que esté interesado.

Como recibimos la posición y el ID de la imagen en Tracks, tenemos todos los datos necesarios para mostrarla y animarla. Primero buscaremos la información del artista (específicamente el nombre y la URL de la imagen) usando la identificación del artista.

Para animar la imagen, necesitamos calcular el transform valor desde la posición inicial de la imagen. Para configurar el transform valor, estoy usando propiedades personalizadas de CSS, que también se pueden hacer con técnicas CSS-in-JS. Tenga en cuenta que la posición de la imagen que recibimos a través de accesorios será relativa a la ventana. Por lo tanto, tendremos que restar algún desplazamiento fijo causado por el relleno del contenedor. <div> para igualar nuestras matemáticas.

const { x, y } = this.$route.params.position
// padding-left
const offsetLeft = 100
// padding-top
const offsetTop = 30

// Set CSS custom property value
document.documentElement.style.setProperty(
	'--translate', 
	`translate(${x - offsetLeft}px, ${y - offsetTop}px) scale(0.792)`
)

Usaremos este valor para crear una animación de fotograma clave para mover la imagen:

@keyframes move-image {
	from {
		transform: var(--translate);
	}
}

Esto se asigna a la animación CSS:

.image {
	animation: move-image 0.6s;
}

…y animará la imagen desde este valor de transformación a su posición original en la carga del componente.

Transición de artistas a pistas

Podemos usar la misma técnica cuando vamos en la dirección opuesta, Pistas a Artistas. Como ya tenemos almacenada la posición de la imagen en la que se hizo clic en el componente principal, también podemos pasarla a accesorios para Artistas.

Transición de pistas a artistas

Paso 5: ¡Muestra las pistas!

Es genial que ahora podamos movernos entre nuestras dos vistas sin problemas, pero la vista de Pistas es bastante escasa en este momento. Así que agreguemos la lista de pistas para el artista seleccionado.

Crearemos un cuadro blanco vacío y un nuevo fotograma clave para deslizarlo hacia arriba al cargar la página. Luego le agregaremos tres subsecciones: Pistas recientes, Pistas populares y Lista de reproducción. Nuevamente, si desea avanzar, siéntase libre de hacer referencia o copiar el código final del repositorio.

La vista de pistas con contenido

Pistas recientes es la fila de miniaturas justo debajo de la imagen del artista, donde cada miniatura incluye el nombre de la pista y la duración de la pista debajo. Ya que estamos cubriendo animaciones aquí, crearemos una animación a escala, donde la imagen comienza invisible (opacity: 0) y un poco más pequeño que su tamaño natural (scale(0.7)), luego se revela (opacity: 1 ) y escala hasta su tamaño natural (transform: none).

.track {
	opacity: 0;
	transform: scale(0.7);
	animation: scale-up 1s ease forwards;
}

@keyframes scale-up {
	to {
		opacity: 1;
		transform: none;
	}
}

La lista de pistas populares y la lista de reproducción se encuentran una al lado de la otra debajo de las pistas recientes, donde las pistas populares ocupan la mayor parte del espacio. Podemos deslizarlos un poco hacia arriba en la vista inicial con otro conjunto de fotogramas clave:

.track {
	...
	animation: slide-up 1.5s;
}

@keyframes slide-up {
	from {
		transform: translateY(140px);
	}
}

Para que la animación se sienta más natural, crearemos un efecto de escalonamiento agregando un retraso de animación incremental a cada elemento.

@for $i from 1 to 5 {
	&:nth-child(#{$i + 1}) {
		animation-delay: #{$i * 0.05}s;
	}
}

El código anterior básicamente busca cada elemento secundario y luego agrega un retraso de 0,05 segundos a cada elemento que encuentra. Entonces, por ejemplo, el primer hijo tiene un retraso de 0,05 segundos, el segundo hijo tiene un retraso de 0,10 segundos y así sucesivamente.

Mira lo agradable y natural que se ve todo esto:

Bonificación: ¡microinteracciones!

Una de las cosas divertidas de trabajar con animaciones es pensar en los pequeños detalles porque son los que unen las cosas y agregan placer a la experiencia del usuario. A estas microinteracciones las llamamos y tienen un buen propósito al proporcionar retroalimentación visual cuando se realiza una acción.

Dependiendo de la complejidad de las animaciones, es posible que necesitemos una biblioteca como anime.js o GSAP. Este ejemplo es bastante sencillo, por lo que podemos lograr todo lo que necesitamos escribiendo algo de CSS.

Primera micro-interacción: El ícono de volumen

Primero obtengamos un ícono de volumen en formato SVG (Noun Project y Material Design son buenas fuentes). Al hacer clic, animaremos la entrada y salida de su path elemento para mostrar el nivel de volumen. Para ello, crearemos un método que cambie su clase CSS según el nivel de volumen.

<svg @click="changeVolume">
	<g :class="`level-${volumeLevel}`">
		<path d="..."/> <!-- volume level 1 -->
		<path d="..."/> <!-- volume level 2 -->
		<path d="..."/> <!-- volume level 3 -->
		<polygon points="..."/>
	</g>
</svg>

Basados ​​en esta clase, podemos mostrar y ocultar ciertas path elementos como:

path {
	opacity: 0;
	transform-origin: left;
	transform: translateX(-5px) scale(0.6);
	transition: transform 0.25s, opacity 0.2s;
}

.level-1 path:first-child,
.level-2 path:first-child,
.level-2 path:nth-child(2),
.level-3 path {
	opacity: 1;
	transform: none;
}

El control de volumen animado

Segunda micro-interacción: El icono favorito

¿Te gusta cuando haces clic en el botón del corazón de Twitter? Eso es porque se siente único y especial por la forma en que se anima al hacer clic. Haremos algo similar pero muy rápido. Para esto, primero obtenemos un ícono de corazón SVG y lo agregamos al marcado. Luego, le agregaremos una animación hinchable que se activa al hacer clic.

@keyframes bounce {
	0%, 100% {
		transform: none;
	}
	30% {
		transform: scale(1.3);
	}
	60% {
		transform: scale(0.9);
	}
}

Otra cosa divertida que podemos hacer es agregar otros íconos de corazones pequeños a su alrededor con tamaños y posiciones aleatorios. Idealmente, agregaríamos algunos absolute-elementos HTML posicionados que un corazón como fondo. Organicemos cada uno de ellos como se muestra a continuación configurando sus left y bottom valores.

También incluiremos un efecto de desvanecimiento para que los íconos parezcan disolverse a medida que se mueven hacia arriba agregando una animación de fotograma clave en el mismo evento de clic.

@keyframes float-upwards {
	0%, 100% {
		opacity: 0;
	}
	50% {
		opacity: 0.7;
	}
	50%, 100% {
		transform: translate(-1px, -5px);
	}
}

El botón favorito animado

Resumiendo

¡Eso es todo! Espero que encuentre todo esto motivador para probar animaciones en sus propios sitios web y proyectos.

Mientras escribía esto, también quería ampliar los principios fundamentales de animación que mencionamos anteriormente porque creo que ayudan a elegir la duración de la animación y evitan animaciones sin sentido. Es importante discutir eso porque hacer animaciones correctamente es mejor que hacerlos en absoluto. Pero esto suena como un tema completamente diferente que se tratará en un artículo futuro.