AlanGarcíaÓrbita
ES ↗
contacto@alangarcia.dev ↗

Al hero le sobraba movimiento

El primer hover del portafolio se sentía brusco. Así fui ajustando la escala, la rotación y el reparto entre Three.js, GSAP y Motion.

Alan García5 min de lectura
Tres recortes de papel ligeramente inclinados, unidos por un hilo verde sobre una mesa de taller oscura

La primera vez que vi las imágenes del hero responder al cursor, el efecto se me hizo demasiado brusco. Se agrandaban, se encimaban y terminaban llamando más la atención de la que quería darles.

Yo buscaba precisamente eso: que la imagen sobre la que pasara el cursor se mostrara un poco más que las otras. Al verla funcionando, tuve que afinar la petición. Quería que se notara, pero que se sintiera discreto.

En la primera entrada de esta bitácora conté por qué renové el portafolio. Esta vez quiero detenerme en ese ajuste, porque ahí se concentraron varias decisiones del movimiento del sitio.

Primero, bajar la escala

El hero tiene tres capturas: TARS, Radar Tlaxcala y HORRORVERSE. Ya están inclinadas y superpuestas, así que la composición tiene bastante información incluso antes de mover el cursor.

La escala del plano seleccionado terminó en 1.018. Es un crecimiento de apenas 1.8 % respecto a su tamaño de reposo. También sube un poco, y las otras capturas bajan ligeramente su opacidad.

Este fragmento sale de la función que actualiza la escena. Está recortado para mostrar solo esa parte:

const focus = index === selected;
const scale = approach(mesh.scale.x, focus ? 1.018 : 1);
mesh.scale.setScalar(scale);

approach acerca el valor actual al destino durante los siguientes fotogramas. Así, entrar y salir de una imagen no provoca un salto inmediato entre dos tamaños.

La profundidad de cada plano conserva su lugar. El énfasis viene del ajuste de escala, la posición vertical y el giro; no de mandar de golpe una captura delante de todas las demás.

Después, darle un poco de giro

Al reducir el efecto, añadí a las imágenes algo más de rotación. Muy leve. Quería recuperar un poco de respuesta sin volver a la sensación anterior.

Hay dos movimientos que se combinan: el grupo completo se inclina con el puntero y el plano seleccionado recibe un ajuste adicional. La dirección del pequeño giro alterna según la imagen. Por eso las tres capas no reaccionan como una sola lámina rígida.

El filtro de color permanece. En las tarjetas de proyectos sí aparece el color original al pasar el cursor; en el hero decidí dejar el tratamiento del sitio. Entre el apilado y la inclinación ya había suficiente respuesta.

El resultado que buscaba era algo que acompañara el recorrido del cursor y volviera a su lugar con calma.

Qué hace cada herramienta

Quise trabajar con Three.js, GSAP y Motion. Tener las tres instaladas no resolvía cómo repartirlas: había que decidir qué controlaba cada una.

Three.js construye la escena del hero: cámara, texturas y planos. La función de render combina la posición del cursor, el plano seleccionado y el progreso del scroll para calcular la composición.

GSAP anima ese progreso del scroll y coordina otras secuencias de la página, como la entrada del menú y la aparición de imágenes al recorrer la portada. En el hero modifica un valor de progreso que la escena después utiliza; no hay dos animaciones independientes intentando imponer el giro final al mismo plano.

Motion responde a interacciones pequeñas en las tarjetas, por ejemplo la flecha de un proyecto o la imagen de una lectura. El ajuste fino de los planos WebGL está en la escena, no en esos hovers de las tarjetas.

El puntero y el progreso de scroll alimentan la escena Three.js. GSAP controla secuencias y progreso; Motion controla pequeños elementos de las tarjetas
Así se reparte el movimiento en este portafolio. Ver diagrama en grande ↗

Esa separación también facilita encontrar dónde tocar algo. Si el giro de una captura se siente exagerado, voy a la escena. Si la entrada del menú tarda demasiado, reviso su secuencia.

La parte que no se ve en una captura

Después del aspecto visual viene el trabajo de apagar lo que ya no hace falta.

La escena pide nuevos fotogramas mientras tiene valores que ajustar. Cuando se estabiliza, deja de hacerlo. También pausa cuando sale de la pantalla o la pestaña queda oculta.

Al salir de la página se cancelan los fotogramas pendientes, se desconectan los observadores y se liberan texturas, geometrías y materiales. La carga de imágenes también contempla que la persona se vaya antes de que termine.

Nada de eso mejora una captura del hero. Sí forma parte de lo que hay que resolver para que el efecto tenga sentido dentro de una página que se usa y se abandona.

Cuando la escena no se activa

Las tres capturas también existen como una composición HTML. Esa es la alternativa si la escena no llega a estar disponible. La preferencia de movimiento reducido evita activar el hero 3D.

El texto y los enlaces de la portada siguen ahí. La animación puede cambiar la forma de presentar los proyectos sin convertirse en un requisito para enterarse de cuáles son.

Todavía queda medir el comportamiento en más dispositivos. No tengo una cifra de FPS que presentar aquí. Lo que sí puedo contar es el cambio concreto que hice: menos crecimiento, un giro pequeño y una respuesta que ya no necesita ocupar toda la atención.

Si tuviera que quedarme con una parte de este proceso, sería esa vuelta al navegador para ver el efecto completo. El número de una escala dice poco hasta que está junto al título, las otras imágenes y el movimiento del cursor.

Puedes verlo en la portada. En la siguiente entrada quiero pasar a un detalle mucho más pequeño: el reloj y lo que ocurre cuando el clima deja de responder.

#threejs#gsap#motion#accesibilidad

UNA IDEA PARA COMPARTIR

Bitácora Digital Craft / 2
← Mi portafolio ya me quedaba cortoEl reloj sigue, aunque el clima no responda →

Detalle del diagrama

HORA / UTC−6

America/Mexico_City · UTC−6
EL CLIMA, AHORA
— °CConsulta el clima actual

Ciudad predeterminada · ubicación solo si la solicitas.

Datos: Open-Meteo · CC BY 4.0

América, México y Ciudad de MéxicoMéxico resaltado y un punto en Ciudad de México, zona horaria del reloj. No representa tu ubicación.
UN PUNTO EN EL MAPA19.43° N / 99.13° W · UTC−6