Caso de estudio · Marca personal

micro.lab + Portafolio

Un ecosistema web de dos caras: laboratorio de microinteracciones para aprender animación frontend, y portafolio profesional para contar mi trayectoria. Todo en HTML, CSS y JavaScript modular — desplegado en Cloudflare Pages con dominio propio.

HTMLCSSJavaScriptCloudflarePWA⏱ 7 min
Rol
Diseño + desarrollo
Tipo
Proyecto personal
Stack
Vanilla web
Deploy
Cloudflare Pages
22demos interactivas
1dominio en producción
0frameworks UI
PWAinstalable / offline ligero

El problema

Un portafolio de junior suele ser una lista de bullets o un template comprado. Yo quería otra cosa: un sitio que demuestre el oficio en vez de describirlo — que se note que controlo el DOM, el CSS y la animación sin esconderme detrás de un framework — y que, de paso, le enseñe algo a quien entra.

La decisión

Lo dividí en dos productos bajo la misma marca:

Y una regla incómoda a propósito: cero frameworks de UI. HTML, CSS y JavaScript modular. Si algo se mueve, es porque yo escribí cómo se mueve.

Tres retos técnicos (con código)

En vez de listar tecnologías, prefiero mostrarte tres problemas reales que tuve que resolver — con el código de verdad y la lección que me dejó cada uno.

Reto 01

Un contador que cobra vida

Los números del portafolio (22 demos, etc.) no aparecen de golpe: suben desde cero y desaceleran al final, justo cuando entran en pantalla. Se siente vivo, pero son solo tres piezas trabajando juntas:

// 1) una curva que desacelera al final (easing) const easeOut = t => 1 - Math.pow(1 - t, 3); // 2) requestAnimationFrame: animar cuadro a cuadro function subir(el, fin, dur = 1400) { const ini = performance.now(); (function paso(ahora) { const t = Math.min((ahora - ini) / dur, 1); el.textContent = Math.round(easeOut(t) * fin); if (t < 1) requestAnimationFrame(paso); })(ini); } // 3) IntersectionObserver: arranca cuando el número se ve new IntersectionObserver(([e], obs) => { if (!e.isIntersecting) return; subir(e.target, +e.target.dataset.cuenta); obs.unobserve(e.target); }).observe(numero);

La lección: una animación que se siente bien casi nunca es azar: es easing (para que no sea lineal y robótico) + el momento correcto (que arranque cuando se ve, no antes).

Reto 02

“Cambié el código y no se veía”

El bug más frustrante del proyecto no fue de lógica: subía un cambio, recargaba… y seguía viendo la versión vieja. Solo en incógnito aparecía lo nuevo. El culpable era la caché — el navegador y el service worker guardaban el CSS/JS viejo. La solución fue pedir el código primero a la red:

// Para mi propio código voy primero a la red, saltándome // la caché del navegador (cache: 'reload'). Si hay internet // muestro lo nuevo y guardo copia; si no, caigo al caché. function redPrimero(req) { return fetch(req, { cache: 'reload' }) .then(res => { guardarCopia(req, res); return res; }) .catch(() => caches.match(req)); } // Y en las cabeceras del hosting, para el código: // Cache-Control: max-age=0, must-revalidate

La lección: en una PWA tu peor enemigo no es un bug, es la caché vieja pegada. “Network-first” para tu propio código = el deploy se ve al primer refresh, no al tercero.

Reto 03

Un solo truco para casi todo el movimiento

El cursor personalizado, el búho mascota y los “seguidores” que persiguen al mouse comparten una sola línea de matemática — interpolación lineal (lerp): en cada cuadro, acércate un porcentaje a la meta.

// lerp: muévete un 15% de lo que te falta, cada frame. pos.x += (destino.x - pos.x) * 0.15; pos.y += (destino.y - pos.y) * 0.15; // 0.15 = qué tan suave se siente. Más bajo = más lento y elegante.

La lección: no necesitas una librería de física para que algo se sienta vivo. Una primitiva pequeña y buena (lerp), bien reutilizada, rinde más que una dependencia de 100 KB.

El resultado

El proyecto vive en pabloaravena.com: HTTPS, deploy continuo desde GitHub a Cloudflare Pages, PWA (manifest + service worker), tema claro/oscuro con transición, bilingüe ES/EN y formulario de contacto. Es a la vez mi carta de presentación y un laboratorio público de frontend — 22 demos que cualquiera puede abrir, leer y copiar.

Lo que aprendí

Hubo días en que tiraba código y no lograba lo que tenía en la cabeza. Pero construir cada pieza a mano me hizo entender por qué funciona, no solo que funciona. Ese es el punto de todo esto: nunca fue un proyecto para lucrar — era para mostrar lo que me gusta hacer y, ojalá, enseñarle algo a alguien que recién parte.

Abrir micro.lab Ver portafolio Repo en GitHub