Cómo construí mi portafolio con efectos 3D, three.js y Astro
Este sitio es, en sí mismo, mi primer caso de estudio. Quería que transmitiera lo que hago —código, diseño e IA trabajando juntos— sin decirlo: que se sintiera al hacer scroll. Aquí van las decisiones que lo hicieron posible, por si te sirven para tu propio proyecto.
Un sistema de diseño antes que píxeles
Antes de escribir una línea de CSS definí los tokens: fondo #0a0a0b, un dorado #d9b65f como acento principal, un teal #46b8a4 como secundario, y tres tipografías con roles claros — Space Grotesk para titulares, Hanken Grotesk para texto y JetBrains Mono para etiquetas técnicas.
La regla que más orden aporta es la más simple: cada acento tiene un significado. El dorado señala lo principal (CTAs, navegación, proyectos destacados); el teal señala exploración (el Lab, lo experimental). Cuando el color comunica, necesitas menos elementos para guiar al usuario.
El fondo 3D: three.js sin pasarse
El fondo es una escena de three.js con dos nubes de partículas (unas 1.100 en escritorio, menos de la mitad en móvil) y dos icosaedros wireframe anidados que rotan en direcciones opuestas.
Tres detalles marcan la diferencia:
- Partículas con sprite circular. Los
Pointsde three.js se dibujan como cuadrados por defecto. UnCanvasTexturecon un gradiente radial las convierte en puntos de luz suaves. - El scroll mueve la cámara, no el DOM. El progreso de scroll acerca la cámara y desplaza el mundo: profundidad real, no un truco de
translateY. - El ratón se suaviza con interpolación. La rotación persigue al cursor con un factor de 0.04 por frame. La escena se siente viva, nunca nerviosa.
Y lo más importante: si el CDN falla o no hay WebGL, la página funciona exactamente igual. El 3D es una capa de mejora, nunca una dependencia.
Rendimiento y accesibilidad como requisitos
Un portafolio que presume de efectos y va a tirones comunica lo contrario de lo que pretende:
- El render se pausa cuando la pestaña no está visible.
- El
devicePixelRatiose limita a 2 para no fundir GPUs en pantallas 4K. prefers-reduced-motiondesactiva todo el movimiento: decode, reveals, parallax, tilt y la animación 3D (queda un frame estático).- Todas las animaciones de scroll usan
IntersectionObservery un único listener conrequestAnimationFrame— nada de cálculos por evento de scroll.
La migración a Astro: SEO sin renunciar a nada
La primera versión era HTML puro. Funcionaba, pero un blog en HTML artesanal no escala: cada post duplicando <head>, sitemap a mano, sin RSS.
Astro resolvió exactamente eso sin cambiar nada del diseño: los estilos, el JavaScript de interacciones y la escena 3D pasaron tal cual a public/. Lo que gané: contenido en markdown, sitemap y RSS automáticos, metadatos y JSON-LD centralizados en un layout, y HTML estático generado en build — cero JavaScript de framework en el cliente.
Para un sitio de contenido con ambición de posicionar, esa combinación —HTML estático, datos estructurados y markdown escalable— es difícil de superar.
Lo que viene
El Lab irá creciendo con demos interactivas, y este blog con lo que aprenda construyéndolas. Si te interesa el detalle de cualquier parte, el código es abierto — y si tienes un proyecto donde aplicarlo, hablemos.