Communitygithub.com

page-swarm-rebuild

Añade el efecto de 'la página se reconstruye sola' a un sitio web existente (HTML plano, React o Next.js): un enjambre de cursores-agente de colores oculta la página terminada y luego la reconstruye capa por capa, siguiendo el desplazamiento del visitante, con movimiento natural.

¿Qué es page-swarm-rebuild?

page-swarm-rebuild es un módulo JavaScript ligero y sin dependencias que implementa un efecto visual de tipo 'la página se reconstruye a sí misma', ideal para presentaciones. Funciona en sitios HTML plano, React y Next.js sin modificar el DOM real: las capas originales se ocultan y revelan mediante una hoja de estilos en cascada en el `<head>`, y toda la animación ocurre en una superposición (`overlay`) que se añade y elimina dinámicamente. El efecto está diseñado para ser respetuoso con el rendimiento (sin desplazamiento de diseño), la accesibilidad (compatible con `prefers-reduced-motion` y sin sonido) y los motores de búsqueda (los rastreadores ven la página completa). El módulo genera un enjambre de cursores animados que seleccionan elementos, muestran marcos con etiquetas de tamaño, escriben texto, revelan imágenes y clonan contenido, todo siguiendo el desplazamiento del usuario. Incluye un modo depuración opcional con barra de control, visita guiada automática y hooks de prueba. Es útil para crear introducciones llamativas para portafolios, landings o presentaciones de producto, donde se quiere mostrar visualmente cómo se 'construye' la página.

Compatible con✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Kiskujab/swarm-skill/tree/HEAD/page-swarm-rebuild

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

¿Qué hace page-swarm-rebuild?

Versión 1.3.0 (módulo, complemento, hoja de estilos y este archivo; consulta CHANGELOG.md en el repositorio; SwarmRebuild.version).

Efecto introductorio solo de presentación. El DOM real de la página nunca se modifica: las capas se ocultan y revelan con una hoja de estilos en cascada en <head>, toda la animación ocurre en una superposición añadida a <html>, y ambas se eliminan al final. Sin dependencias, sin solicitudes de red (respetuoso con GDPR), sin desplazamiento de diseño, sin sonido, y la página nunca queda medio oculta (ver Protección).

Especificación del efecto original (línea de tiempo, elementos visuales, HUD, curva de desplazamiento): references/effekt-leiras.md (húngaro). Donde este archivo y ese difieran, este archivo tiene prioridad (las decisiones de producto se tomaron después de redactar la descripción).

Archivos

ArchivoPropósito
assets/swarm-rebuild.jsEl módulo, código fuente legible (script clásico, establece window.SwarmRebuild; también importable desde un empaquetador).
assets/swarm-rebuild.min.js, swarm-rebuild-debug.min.js, swarm-rebuild.min.cssCompilaciones minificadas para sitios HTML plano (scripts/build-min.cjs; el instalador las usa; los empaquetadores minifican las fuentes por sí mismos).
assets/swarm-rebuild.cssEstilos de la superposición, todos con ámbito bajo #swarm-rebuild-root.
assets/swarm-rebuild-debug.jsComplemento de depuración: barra de control, visita guiada automática, hooks de prueba. Nunca se carga para visitantes; se obtiene solo con ?rebuild-debug=1 / debug: true. Instálalo junto al módulo de todas formas (así es como pruebas en el sitio en vivo).
assets/react/SwarmRebuild.jsxEnvoltorio React/Next.js del lado cliente + <SwarmRebuildHead /> (fragmento previo a la pintura); el complemento de depuración es un fragmento perezoso separado.
assets/demo/Demo ficticio de portafolio oscuro (assets/demo/index.html, 214 capas (escritorio), 6.6 alturas de ventana gráfica, encabezado fijo).
tests/index.htmlEnlaces a todas las páginas de prueba en todos los modos (también la página de inicio de GitHub Pages).
tests/pages/dental/Consultorio dental ficticio: tema claro, enlaces telefónicos, barra fija "Llámanos" + reserva (móvil), aviso fijo (escritorio).
tests/pages/lang-*/Páginas ficticias en húngaro, árabe (derecha a izquierda), japonés y una rica en emojis (escritura en cualquier idioma).
tests/pages/law/, accounting/, bootstrap/, spa/Patrones ficticios del mundo real: fuentes web, encabezado fijo, banners de consentimiento, iframe, imágenes perezosas, modo oscuro, página larga, desplazamiento-revelado, Bootstrap (npm), aplicación de una sola página, videos.
tests/pages/nextjs/Aplicación ficticia Next.js 15 App Router: contador React (verificación de hidratación), botón de ayuda fijo.
scripts/verify.cjsVerificación con Playwright de una página (ver paso 4).
scripts/run-tests.cjsEjecuta verify.cjs en las tres páginas de prueba, escritorio y móvil; imprime una tabla resumen.
scripts/bench-fps.cjsVelocidad de fotogramas de una versión anterior del módulo frente a la actual, misma máquina, ejecuciones intercaladas.
scripts/build-site.cjsConstruye las tres páginas de prueba como un solo sitio estático (GitHub Pages) o lo sirve en la red local.
scripts/next-app.cjsAyudante: prepara / construye la aplicación de prueba Next.js en una carpeta temporal.
scripts/build-min.cjsConstruye los archivos .min y verifica el presupuesto de tamaño (necesita terser y csso de npm).
scripts/perf.cjsMétricas Lighthouse (LCP, CLS, TBT, Speed Index, accesibilidad, SEO) con y sin el efecto.
scripts/sync-snippet.cjsCopia el fragmento de cabeza del módulo en el envoltorio React, SKILL.md y las páginas de prueba.
scripts/record-video.cjsGraba el efecto como .mp4 / .webm para un portafolio (la visita guiada de depuración, barra de control oculta).
scripts/project.cjsInstala el efecto en un proyecto con una copia de seguridad en legacy/, lo elimina nuevamente, restaura los originales.
scripts/test-project.cjsPrueba el instalador: copia de seguridad, restauración después de un proyecto roto (idéntico en hash), desinstalación.

Decisiones de producto (anulan el video de referencia)

  • El modo principal es scroll (el predeterminado): la construcción sigue el desplazamiento del visitante, y solo se construye lo que está en la ventana: un elemento comienza cuando al menos el 60 % de él está en pantalla (buildVisible), no se construye nada por debajo ni por encima de la vista, y ningún agente activo sale nunca de la pantalla.
  • Los visitantes nunca ven una barra de control y nunca obtienen un desplazamiento automático. La barra y la visita guiada viven en el complemento de depuración, cargado solo con ?rebuild-debug=1 o debug: true. mode: 'tour' sin el complemento vuelve a scroll.
  • Siempre hay una salida sin controles visibles: Escape, Tabulador, Enter, cualquier otra tecla (excepto Mayús/Ctrl/Alt/Meta solas) y cualquier clic o toque muestran la página terminada de inmediato, sin animación ni desplazamiento de diseño. prefers-reduced-motion significa que no hay efecto en absoluto (WCAG 2.2.2).
  • Las teclas de desplazamiento desplazan: Espacio, las flechas, Re Pág / Av Pág e Inicio / Fin (con el foco en la página misma, sin Ctrl / Alt / Meta) impulsan la construcción exactamente como la rueda del ratón. En un enlace, botón o campo enfocado, o con un modificador, finalizan el efecto como cualquier otra tecla. Tabulador, Enter y Escape siempre lo finalizan, por lo que los usuarios de teclado llegan al contenido real (y su orden de foco) en su primer Tabulador.
  • El clic que finaliza el efecto nunca hace algo que el visitante no vio: si cae en contenido que aún no estaba terminado (oculto, o aún en construcción), se traga (preventDefault + stopPropagation, en el ratón ya en pointerdown, por lo que no hay foco, ni enlace, ni acción de botón). Si cae en contenido terminado (visible, nada dentro de él o revelándolo aún en progreso — p.ej., un enlace telefónico, que se muestra desde el principio, o un botón construido), pasa como un clic normal y el efecto finaliza al mismo tiempo. Motivo: tragar cada clic haría que un enlace "Llámanos" visible fallara en el primer toque; dejar pasar cada clic seguiría enlaces que el visitante nunca vio. El desplazamiento táctil y la barra de desplazamiento nunca finalizan el efecto (desplazarse es cómo se impulsa la construcción).
  • Sin sonido. El módulo no tiene código de audio.

Modos

modovelocidadcomportamiento
scroll (predeterminado)3xSin desplazamiento automático. Los agentes construyen solo lo que está en la vista: un elemento comienza cuando al menos buildVisible (60 %) de su altura está en pantalla; un elemento más alto que la pantalla cuando llena el 60 % de la pantalla, por lo que se construye de arriba a abajo a medida que entra. No se construye nada fuera de la vista y un agente activo nunca la abandona (un marco más alto que la pantalla se tira desde el borde de la pantalla). Después de un desplazamiento rápido (rueda, teclas, Inicio / Fin), la parte visible se completa en ~1-2 s: esas capas comienzan primero, se unen más agentes (hasta 8 por encima del plan) y las tareas se ejecutan más rápido. Lo que sale de la vista se finaliza de inmediato (ver Protección).
fast6xIgual que scroll, el doble de rápido.
tour (solo depuración)1xDesplazamiento automático como en el video de referencia: ~capas/7 segundos, la cámara sigue el frente de trabajo, termina en la parte inferior con el anillo de cursores. Para grabaciones y verificaciones lado a lado. ?rebuild-speed=6 da el antiguo "rápido" (un desplazamiento automático de 6x, ~9 s en la demo). El desplazamiento manual entrega el control al visitante; el botón Tour de la barra lo reanuda.

Después de la construcción, los enjambres se reúnen alrededor del elemento de enfoque y la superposición desaparece después de autoExit segundos (3 s; con el complemento de depuración 6 s, nunca en modo tour).

Movimiento

Todo es sutil por defecto y se configura con motion (ver Configurar); ?rebuild-motion=arc:0,... desactiva partes para pruebas A/B (complemento de depuración).

  • Elemento de enfoque (focus): la apertura y el final se arremolinan alrededor de él. Pregunta al desarrollador (paso 1). En cada fase, el primero de estos que esté al menos medio visible se usa: el(los) elemento(s) configurado(s), [data-swarm-focus], h1, un botón principal (a.btn, .button, .cta, button[type=submit] ...), el logotipo; luego la imagen más grande visible; luego un punto en la vista. Así, un enfoque muy abajo en la página (p.ej., una llamada a la acción final) sirve para el final, y la apertura usa el encabezado principal.
  • Enjambres: los agentes libres vuelan en 2-4 enjambres de tamaños claramente diferentes (teléfonos: 2). Cada agente es jalado por un resorte amortiguado hacia su lugar en su enjambre; los centros del enjambre se mueven en una elipse alrededor del elemento de enfoque cuyo radio respira y cuyo ritmo cambia, por lo que los agentes aceleran y desaceleran por sí mismos y nunca corren en un círculo perfecto. La apertura ya comienza en enjambres (dura menos de un segundo para los visitantes).
  • Agentes en reposo (durante la construcción, un agente sin trabajo): abandona su enjambre para ocupar su propio punto en la vista, al menos a 72 px de cualquier otro agente en reposo (nunca un grupo de cursores superpuestos), se desplaza lentamente y se desvanece después de 1.4 s; aparece donde descansa cuando recibe su próxima tarea. En el final, todos regresan y se reúnen en enjambres alrededor del enfoque. Medido: como máximo 2 cursores en reposo superpuestos en el 99.6-100 % de los fotogramas (1.2: una mediana de 6 y hasta 20 en la demo).
  • Final: un resorte rígido y subamortiguado (amortiguación 0.63, motion.spring) jala a cada agente hacia el enfoque: más rápido al inicio, aproximadamente 5-20 % más allá de su lugar, luego de regreso; después de ~1 s, el resorte se suaviza y los enjambres giran lentamente.
  • Ratón (apertura y final, solo escritorio; nunca al tacto, nunca con movimiento reducido): un agente cerca del puntero se aparta de su camino (más difícil cuando el puntero viene rápido); hasta 3 agentes curiosos lo siguen en un círculo pequeño, 1.3-2 s cuando descansa, más corto cuanto más rápido se aleja (el interés disminuye a (1 + velocidad / 220 px/s) veces la tasa base). Nunca más cerca de 36 px (un límite estricto, por lo que los iconos nunca se superponen); la superposición ignora los eventos del puntero, por lo que los clics nunca se interrumpen.
  • Gravedad: un agente lleva el elemento en el que trabaja, por lo que su camino allí (y una copia clonada que lleva) se dobla hacia abajo: pandeo = 0.2 x distancia horizontal x peso x horizontalidad², peso = sqrt(área) / 320 px limitado a 0.2..1, como máximo 56 px y una quinta parte de la distancia horizontal. Un movimiento vertical apenas se dobla. El camino hacia una tarea también comienza con la velocidad actual del agente (curva cúbica de Hermite), por lo que no hay paradas o giros repentinos.
  • Dificultad: el trabajo de cada tarea (no el camino) se escala por una dificultad según el área del elemento (para escritura: el cuadro donde se escribe): cerca del promedio de la página, 2x el área ~ 1.6-1.8x el tiempo, comprimido (tanh) para que la tarea más difícil tome como máximo ~4x la más fácil. Se normaliza (ponderado por la longitud de la tarea y la dificultad, porque las tareas paralelas hacen que las largas marquen el ritmo) para que toda la construcción tome el mismo tiempo que antes; solo cambia la división entre pequeñas y grandes.
  • Lite (motion.lite: 'auto'): en teléfonos, 2 enjambres y sin juego del ratón; cuando la velocidad de fotogramas se mantiene por debajo de 38 fps durante dos segundos durante la construcción, también un fantasma de estela en lugar de tres.

Idiomas y direcciones de escritura

El módulo no asume ningún idioma. La escritura se realiza mediante caracteres percibidos por el usuario (clústeres de grafemas, Intl.Segmenter, con un fallback que une marcas combinantes, secuencias ZWJ, tonos de piel, selectores de variación y pares de banderas): una letra acentuada, una familia emoji, una bandera o una letra con marcas árabes/hebreas nunca se divide. El texto no escrito permanece en su lugar como texto oculto, y los navegadores le dan forma a través de ese límite, por lo que las letras árabes mantienen sus formas unidas y nada se refluye. Elementos de derecha a izquierda (direction: rtl, p.ej., <html dir="rtl">): los marcos crecen desde el borde derecho, las líneas se dibujan de derecha a izquierda, el agente escribe en el lado izquierdo y el cursor se sitúa a la izquierda de la última letra escrita; una secuencia de izquierda a derecha dentro de texto de derecha a izquierda (un número, una dirección de correo electrónico, un nombre latino) se escribe como un todo, como una palabra pegada. El texto CJK (sin espacios) y las palabras largas se envuelven exactamente como en la página. La superposición en sí siempre se diseña de izquierda a derecha (direction: ltr en su raíz) para que una página de derecha a izquierda nunca la refleje. Los números en cualquier escritura (\p{Nd}) cuentan como números. Páginas de prueba: tests/pages/lang-hu (ő / ű, palabras muy largas), lang-ar (derecha a izquierda, dígitos arábigo-índicos, una cita hebrea), lang-ja (japonés), lang-emoji. Límite conocido: los modos de escritura vertical (writing-mode: vertical-rl) se escriben, pero los marcos aún crecen de izquierda a derecha.

Rendimiento, motores de búsqueda, accesibilidad

  • Tamaño (lo que descarga un visitante; el complemento de depuración nunca): módulo 70 KB minificado / 27.5 KB gzip, hoja de estilos 6 KB / 1.6 KB; presupuesto 30 KB + 2 KB gzip (node scripts/build-min.cjs --check). Reconstruye los archivos .min después de cada cambio en el módulo (--modules <carpeta con terser y csso>).

  • Lighthouse (scripts/perf.cjs, mediana de 3, preajustes móvil/escritorio, la máquina de prueba sin GPU):

    páginaLCP ms off -> onCLS off -> onTBT ms off -> onSpeed Index ms off -> onpuntuación perf
    demo, móvil2106 -> 22070 -> 012 -> 10968 -> 166999 -> 99
    demo, escritorio483 -> 5730 -> 00 -> 0266 -> 681100 -> 100
    dental, móvil1956 -> 20350 -> 00 -> 0754 -> 176399 -> 99
    dental, escritorio442 -> 4900 -> 00 -> 0201 -> 767100 -> 100
    law (fuentes web), móvil2094 -> 22220.030 -> 00 -> 01895 -> 238698 -> 97
    accounting (página larga), móvil1707 -> 19730 -> 00 -> 01652 -> 169799 -> 98

    Sin tiempo de bloqueo y sin desplazamiento de diseño (el cambio de fuente propio de la página law incluso se oculta). LCP crece de 50 a 270 ms y Speed Index hasta ~1 s: la primera vista se construye frente al visitante, por lo que está visualmente completa más tarde — ese es el efecto en sí. Solo los visitantes primerizos (una vez por sesión) lo pagan; los visitantes que regresan y los rastreadores obtienen la página de inmediato. Las puntuaciones de accesibilidad/SEO se mueven un punto en cualquier dirección solo porque Lighthouse ve menos de la página mientras está oculta.

  • Motores de búsqueda y vistas previas de enlaces: los rastreadores (agente de usuario con bot / crawl / spider, Googlebot, Bingbot, facebookexternalhit, vistas previas de enlaces ...) nunca reciben el efecto, ni en el fragmento de cabeza ni en el módulo: ven la página terminada con el DOM idéntico (verificación a11y). Sin JavaScript, la página nunca se oculta, y el efecto nunca elimina contenido (solo usa visibility).

  • Accesibilidad (verificación a11y): el contenido oculto por el efecto (visibility: hidden) es invisible para los lectores de pantalla (ARIA no es necesario), y el efecto, mientras se ejecuta, no interfiere con el foco porque la superposición tiene aria-hidden="true" y tabindex="-1", y los eventos de teclado se manejan solo para finalizar el efecto. Al finalizar, la superposición se elimina y el foco vuelve al contenido de la página. La verificación a11y (en scripts/verify.cjs) ejecuta axe-core en la página terminada (sin el efecto), en la página durante el efecto (solo la superposición visible) y después de que el efecto termina, y todas pasan sin violaciones críticas.

Protección

  • Tiempo de espera de capa: una capa que tarda más de 6 s (desde que comienza a construirse) se finaliza para que la página no se quede colgada. Los agentes que faltan se omiten, el marco se oculta y la capa se muestra.
  • Tiempo de espera de agente: un agente que tarda más de 4 s en llegar a su tarea (camino bloqueado, página oculta) se teletransporta y comienza la tarea. El tiempo de espera se duplica si la tarea está lejos (distancia > 2000 px).
  • Tiempo de espera de construcción: si la construcción (todas las capas) no termina en 60 s (modo scroll) o 120 s (modo tour), la página se muestra por completo y el efecto se detiene. El tiempo de espera se reinicia si el visitante se desplaza a una nueva sección (en modo scroll).
  • Ventana oculta: si el documento no está visible (pestaña en segundo plano, ventana minimizada), los agentes se pausan y las tareas no avanzan. Cuando la ventana vuelve a ser visible, la construcción se reanuda desde donde se detuvo, con un breve retraso para evitar un pico de CPU.
  • Redimensionamiento: si la ventana se redimensiona durante la construcción, las posiciones de los marcos y los agentes se recalculan para la nueva ventana gráfica. Los elementos que salen de la vista se finalizan.
  • Fallback sin JavaScript: si JavaScript está deshabilitado, la página se muestra normalmente (la hoja de estilos en <head> no oculta nada porque la clase swarm-rebuild-active nunca se añade). El módulo se carga de forma asíncrona (defer o type="module"), por lo que no bloquea la renderización.

Instalación

HTML plano

  1. Añade los archivos minificados a tu proyecto (swarm-rebuild.min.js, swarm-rebuild.min.css).
  2. En el <head> de tu página, añade el fragmento de cabeza (ver más abajo).
  3. Justo antes de </body>, añade: <script src="ruta/a/swarm-rebuild.min.js"></script> <script>SwarmRebuild.init({ /* opciones */ });</script>

React / Next.js

  1. Instala el paquete desde npm (o copia la carpeta assets/react/ a tu proyecto).
  2. Importa el componente SwarmRebuild desde 'page-swarm-rebuild/react'.
  3. Coloca <SwarmRebuildHead /> en el <head> de tu diseño (o en layout.tsx para Next.js).
  4. Renderiza <SwarmRebuild /> como un componente hijo de tu página (o en un layout).

Fragmento de cabeza

<style>
  .swarm-rebuild-active .swarm-rebuild-layer {
    visibility: hidden !important;
  }
</style>
<script>
  if (window.matchMedia('(prefers-reduced-motion: no-preference)').matches &&
      !/bot|crawl|spider/i.test(navigator.userAgent)) {
    document.documentElement.classList.add('swarm-rebuild-ready');
  }
</script>

Configuración

SwarmRebuild.init() acepta un objeto de opciones:

OpciónTipoPredeterminadoDescripción
modestring'scroll''scroll', 'fast', 'tour'
speednumber1Multiplicador de velocidad de construcción (1 = normal).
focusstring / string[]nullSelector(es) CSS para el(los) elemento(s) de enfoque.
autoExitnumber3Segundos antes de que la superposición desaparezca después de la construcción.
buildVisiblenumber0.6Fracción de un elemento que debe estar visible antes de que comience la construcción (0-1).
motionobject{}Configuración de movimiento (ver más abajo).
debugbooleanfalseCarga el complemento de depuración (solo si la URL tiene ?rebuild-debug=1).
onReadyfunctionnullLlamado cuando el módulo está listo (después de que el DOM esté listo y la superposición esté añadida).
onCompletefunctionnullLlamado cuando la construcción termina (después de que la superposición desaparece).

Opciones de movimiento (motion)

OpciónTipoPredeterminadoDescripción
swarmsnumber3Número de enjambres (1-4).
agentsnumber12Número de agentes (4-40).
spring.dampingnumber0.63Amortiguación del resorte del final (0-1, menor = más elástico).
spring.stiffnessnumber0.03Rigidez del resorte del final (0-1, mayor = más rápido).
mouse.curiousbooleantrueSi los agentes siguen el ratón (solo escritorio).
mouse.distancenumber36Distancia mínima de los agentes al ratón (px).
mouse.interestnumber1.5Duración del interés del ratón (segundos).
gravitynumber0.2Factor de curvatura gravitacional (0 = sin curvatura).
litestring'auto''auto' (detecta bajo rendimiento), 'on' (siempre modo ligero), 'off' (nunca).
trailsnumber3Número de imágenes fantasma de estela (0-5).

Ejemplo

SwarmRebuild.init({
  focus: '.hero h1',
  mode: 'scroll',
  speed: 1.5,
  motion: {
    swarms: 2,
    agents: 8,
    mouse: { curious: false }
  },
  onComplete: () => console.log('¡Construcción completada!')
});

Licencia

MIT

Repositorio

https://github.com/Kiskujab/page-swarm-rebuild

Skills relacionados