Cómo se hizo · Guía técnica

La colmena: retícula hexagonal viva, sin una sola librería

Rediseño de la home de CyberSenseAI en torno a una metáfora única — equipos híbridos como colmena que colabora — construido en un solo HTML autocontenido: canvas 2D a mano, SVG animado, CSS con carácter y cero dependencias externas más allá de Google Fonts.

← Volver a la colmena

01 · ConceptoLa metáfora manda

El producto de CyberSenseAI son Personas IA que se incorporan a equipos humanos. La colmena es la metáfora exacta: individuos distintos, celdas contiguas, un producto común. Cada decisión visual deriva de ahí:

02 · Paleta y tipografíaÁmbar miel · negro cera · blanco panal

Un dominante casi monocromo (cera) con un solo eje de acento (la familia miel) y el blanco panal reservado para lo humano. Nada de gradientes fríos: hasta el fondo del canvas es un degradado de ceras.

Fraunces display

Serif variable con calidez de miel y wonk editorial. Titulares en 420–530 de peso; las palabras clave en itálica ámbar.

Archivo — texto e interfaz

Spline Sans Mono — datos

Grotesk seca para el cuerpo; la mono, en mayúsculas espaciadas, etiqueta celdas, cifras y certificaciones como si fueran marcas de apiario.

03 · La técnica centralCanvas 2D: la colmena que respira

El héroe es un canvas 2D escrito a mano (~200 líneas). No hay mundo pre-generado: la colmena es infinita y determinista. Cada celda axial (q, r) obtiene su papel — vacía, miel, humano o Persona IA — de un hash entero sin estado, así el mundo es estable entre fotogramas y entre visitas, sin guardar nada:

function hash(q, r){
  var n = q*374761393 + r*668265263;
  n = (n ^ (n>>13)) | 0;
  n = (n * 1274126177) | 0;
  n = (n ^ (n>>16)) >>> 0;
  return n / 4294967295;      // 0..1 estable por celda
}
// papel de la celda: <4% humanos, <8.5% Personas IA, <15% miel

La cámara vive en coordenadas mundo y el scroll del héroe (230vh con viewport sticky) gobierna el zoom: de s = 2.5 (celdas en primer plano) a s = 1.05 (la colonia entera), con deriva senoidal lenta para que nunca esté quieta:

var p = smooth(progresoHero);          // scroll 0..1 suavizado
cam.s = 2.5 - 1.45*p;                   // zoom out orquestado
cam.x = Math.sin(t*0.05)*26 + 30;       // deriva de enjambre
ctx.setTransform(DPR*s, 0, 0, DPR*s,
  DPR*(W/2 - cam.x*s), DPR*(H/2 - cam.y*s));
// solo se itera el rango (q, r) visible tras invertir la transformación

Los flujos de miel-datos son pulsos que nacen en una celda ocupada y caminan 3–7 pasos por vecinos axiales (prohibido deshacer el último paso), dibujados como estela ámbar + sprite de brillo pre-renderizado. Las celdas de miel se llenan con un gradiente recortado por el propio trazado hexagonal (clip()), con menisco brillante. El cursor también participa: la celda bajo el ratón se enciende, sus vecinas suben de opacidad y un halo ambiental de miel — un único drawImage del sprite de brillo en coordenadas mundo — lo sigue por la retícula.

La colmena también responde al tacto: un clic o toque sobre el canvas hace nacer una ráfaga de cinco pulsos en la celda tocada, que se reparten por sus vecinas con el mismo caminante axial de los pulsos ambientales (con tope de pulsos vivos para no comprometer los 60 fps). Las celdas que contienen miel refuerzan además la opacidad de su pared: sin ese refuerzo el relleno leía como un rectángulo flotante en vez de una celda cerrada. Y la misma mecánica cierra la carga: dos segundos después del revelado del titular, una ráfaga de bienvenida nace en la celda etiquetada de SoulBot — la colmena saluda reutilizando el código del tacto, sin una línea nueva de dibujo (y se omite si el visitante ya hizo scroll).

El scroll no solo aleja la cámara: dispara una ola de activación. Los umbrales del hash que deciden el papel de cada celda crecen con el progreso — a colmena abierta hay más humanos, más Personas IA, más miel y más pulsos simultáneos. La zona del titular nace despejada (sin ocupantes detrás del texto) y solo se puebla cuando el copy ya salió de escena, desvanecido y elevado por la misma coreografía. Debajo de todo, una capa lejana de panal macro (celdas 3× a mitad de parallax) da profundidad de campo con ~30 hexágonos extra por fotograma.

04 · RendimientoUn stroke por opacidad, no por celda

Con el zoom abierto hay ~340 celdas visibles. Trazarlas una a una (340 stroke() con su cambio de estilo) era el cuello de botella medido en headless. La solución: cuantizar la opacidad de cada pared de cera y acumular los hexágonos en un Path2D por cubo — el fotograma pasa de cientos de strokes a ~15:

var cubo = Math.round(alfa*40);              // pasos de 0.025
var pth = buckets[cubo] || (buckets[cubo] = new Path2D());
hexEnPath(pth, c.x, c.y, R-2.5);
// ...tras el bucle:
for (var kb in buckets){
  ctx.strokeStyle = "rgba(242,169,28," + (kb/40).toFixed(3) + ")";
  ctx.stroke(buckets[kb]);
}

05 · Detalles que venden la metáforaEtiquetas proyectadas y gotas SMIL

Tres celdas fijas del mundo (SoulBot · Persona IA, Humana · Operaciones, Persona IA · Análisis) llevan etiquetas HTML reales, proyectadas cada fotograma de coordenadas mundo a pantalla con la misma cámara del canvas — se mueven, escalan y se desvanecen con el zoom como si estuvieran dentro de la colmena:

var sx = (cc.x - cam.x)*s + W/2, sy = (cc.y - cam.y)*s + H/2;
tag.style.transform = "translate("+sx+"px,"+sy+"px) translateY(-50%)";
tag.style.opacity = clamp(1 - progresoHero*2.4, 0, 1);

En el diagrama de equipo híbrido (3 humanos + 2 Personas IA + tablero compartido), las gotas de miel-datos viajan con SMIL animateMotion dentro del SVG: escalan con el viewBox en cualquier ancho — un begin negativo las arranca ya en mitad del camino, sin destello inicial en el origen. Las celdas de estadísticas se llenan con un <rect> recortado por clipPath hexagonal cuya transformación se transiciona por CSS al entrar en viewport, sincronizada con contadores en requestAnimationFrame.

06 · Movimiento y accesibilidadUna carga orquestada, un fallback digno

07 · DecisionesLo que se descartó