CommunityImagengithub.com

swarm-build

Añade la animación swarm-build a un sitio web, donde un enjambre de cursores de colores con nombre dibuja cuadros y construye una captura de pantalla región por región, o reconstruye una página en vivo bloque por bloque, como un archivo de diseño multijugador.

¿Qué es swarm-build?

swarm-build es una biblioteca JavaScript sin dependencias (aproximadamente 600 líneas) que proporciona dos modos para crear animaciones de construcción visuales e impactantes: modo imagen y modo página. En modo imagen, un lienzo en blanco cubre una imagen y un enjambre de cursores coloreados arrastra recuadros sobre regiones específicas, mostrando una etiqueta en vivo con el tamaño (ancho × alto) de cada región, para que la imagen parezca construirse pieza por pieza. En modo página, los elementos marcados con `data-swarm-block` desaparecen inicialmente y luego los cursores los reconstruyen uno a uno, escribiendo los bloques de texto plano (títulos, párrafos cortos) y esperando a que los elementos contenedores se terminen antes de construir su contenido. La animación respeta la preferencia de movimiento reducido del usuario, no deja rastros en el DOM al finalizar y es compatible con frameworks modernos como React, Next.js, Vue, Svelte y Astro. Es ideal para crear heroínas que se autoconstruyen, efectos multijugador tipo Figma o para dar vida a capturas de pantalla de productos.

Compatible con~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/habom2310/swarm-build/tree/HEAD/skills/swarm-build

Installed? Explore more Imagen skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Preguntar en tu IA favorita

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

Vista previa

Del README del skill

swarm-build preview

Documentación

¿Qué hace swarm-build?

swarm-build es un módulo ES único sin dependencias (src/swarm-build.js, aproximadamente 600 líneas) más un archivo CSS opcional (src/swarm-build.css). Tiene dos modos:

  • Modo imagen, swarmBuild(img): un lienzo en blanco cubre un <img> (o un elemento con una background-image CSS), y cada región de la imagen aparece después de que un cursor arrastra su recuadro mostrando una etiqueta en vivo A × A.
  • Modo página, swarmBuildPage("[data-swarm-block]"): los elementos marcados de una página en vivo desaparecen, luego los cursores los reconstruyen uno por uno. Los bloques de texto plano (títulos, párrafos cortos) se escriben solos. Un bloque dentro de otro espera a su contenedor. Los bloques que están debajo del pliegue esperan hasta que se vean al hacer scroll, por lo que el enjambre sigue al lector por la página.

En ambos modos, los cursores se van al final y todos los cambios realizados por la biblioteca se deshacen.

1. Instalación

Copia src/swarm-build.js, src/swarm-build.d.ts y src/swarm-build.css de este repositorio al proyecto (por ejemplo lib/swarm-build/) e impórtalos con rutas relativas. No hay dependencias ni paso de compilación.

Solo si npm view swarm-build muestra que el paquete está publicado: npm install swarm-build, luego import { swarmBuild } from "swarm-build" y import "swarm-build/style.css".

2a. Modo página: marcar los bloques

  1. Lee el marcado de la página y elige los bloques que dibujaría un diseñador: barra de navegación, encabezado de héroe, párrafo de héroe, cada botón, cada tarjeta, gráfico, tabla, pie de página. Una página de inicio típica tiene de 25 a 60 bloques.
  2. Agrega data-swarm-block a cada uno.
    • Marca los contenedores (una tarjeta) y el texto dentro de ellos (su título y párrafo) para obtener "primero el marco, luego rellénalo".
    • Marca los títulos y párrafos cortos cuyo contenido sea texto plano: esos se escriben solos. Los elementos con marcado en línea (enlaces, <b>) se barren en su lugar.
    • Omite los envoltorios que solo hacen diseño (cuadrículas, secciones sin fondo propio). Ocultarlos oculta todo lo que hay dentro de una vez.
  3. No marques interfaces fijas o fijadas que el visitante necesite de inmediato, como un banner de cookies o un widget de chat.
  4. Llámalo después de que el contenido esté en el DOM:
import { swarmBuildPage } from "./lib/swarm-build/swarm-build.js";
swarmBuildPage("[data-swarm-block]", { speed: 1.5 });

Para ocultar los bloques antes de que se ejecute el script (sin destello de la página terminada), agrega también data-swarm-pending a cada bloque e incluye el archivo CSS.

2b. Modo imagen: elegir las regiones

Las regiones deciden qué se construye y en qué orden. Las buenas regiones hacen que la animación se vea intencionada, así que no te saltes este paso.

  1. Abre la imagen y mírala (lee el archivo de imagen o toma una captura de pantalla de la página).
  2. Enumera los 6 a 15 bloques significativos que dibujaría un diseñador: barra de navegación, encabezado, barra de búsqueda, tarjetas, gráfico, lista, pie de página.
  3. Escribe cada bloque como x y a a en porcentaje del ancho y alto de la imagen (0 a 100). Mide a partir del tamaño en píxeles: x = izquierda / anchoImagen * 100.
  4. Ordénalos de la forma en que una persona construiría la pantalla: primero el marco (barra, encabezado), luego el contenido de arriba a abajo.
  5. Deja pequeños espacios. Cualquier cosa que no cubra ninguna región aparece cuando el lienzo se desvanece al final, por lo que las regiones no necesitan cubrir cada píxel.

Ponlas en la imagen como data-swarm-regions="0 0 18 100, 21 3.5 47 5.5, ...", o pasa regions: [{ x, y, w, h }] en JavaScript. Sin regiones, la biblioteca usa un diseño genérico de barra lateral, encabezado y tarjetas, que rara vez coincide con la imagen.

3. Integración

HTML simple:

<link rel="stylesheet" href="/lib/swarm-build/swarm-build.css" />
<img src="/shot.png" alt="..." width="1200" height="800"
     data-swarm-pending
     data-swarm-regions="0 0 18 100, 21 3.5 47 5.5, 21 13 24 16" />
<script type="module">
  import { swarmBuild } from "/lib/swarm-build/swarm-build.js";
  swarmBuild(document.querySelector("img[data-swarm-regions]"));
</script>

React o Next.js (componente cliente):

"use client";
import { useEffect, useRef } from "react";
import { swarmBuild } from "@/lib/swarm-build/swarm-build.js";

export function BuiltImage(props: React.ComponentProps<"img"> & { regions: string }) {
  const ref = useRef<HTMLImageElement>(null);
  useEffect(() => {
    const swarm = swarmBuild(ref.current!);
    return () => swarm.destroy();
  }, []);
  const { regions, ...img } = props;
  return <img ref={ref} {...img} data-swarm-pending="" data-swarm-regions={regions} />;
}

Para Vue, Svelte o Astro, haz lo mismo: llama a swarmBuild(el) después del montaje y a destroy() al desmontar. Varias imágenes (por ejemplo, un iPad y un teléfono) pueden compartir un mismo enjambre: swarmBuild([ipadImg, phoneImg]).

4. Opciones

OpciónPredeterminadoUso
regions (por objetivo)data-swarm-regions, luego genéricoQué construir, en orden
agents6 nombres y colores integrados[{ name, color, text }], que coincida con la paleta y audiencia del sitio
speed12 reduce la duración a la mitad (aproximadamente 6 a 8 s en 1 para 10 a 15 regiones)
start"visible""now" comienza de inmediato en lugar de cuando la imagen aparece al hacer scroll
canvas"#fff"Color del lienzo sin construir; que coincida con el fondo de la captura de pantalla
zIndex2147483000Apilamiento de la capa fija del cursor; redúcelo si un modal o encabezado debe estar encima
onDoneningunoSe llama una vez cuando la construcción se completa o se llama a finish()
typeSpeed (modo página)1Velocidad del texto escrito; 2 escribe el doble de rápido

El valor devuelto tiene finished, finish() y destroy():

  • finished es una Promesa que siempre se resuelve, sin importar cómo termine el enjambre.
  • finish() salta a la imagen terminada y se ejecuta onDone.
  • destroy() elimina todo ahora y onDone no se ejecuta. Llámalo al desmontar.
  • setSpeed(n) cambia la velocidad mientras se ejecuta.

En modo página, start predetermina a "now"; en modo imagen, a "visible".

5. Reglas a mantener

  • data-swarm-pending más el archivo CSS mantienen la imagen oculta hasta que el script comience, por lo que no destella terminada primero. Si el script nunca se ejecuta, el CSS muestra la imagen después de 4 segundos. Omite el atributo cuando la imagen es el elemento LCP de la página y el tiempo de carga importa más que el efecto.
  • Movimiento reducido (prefers-reduced-motion: reduce) muestra la imagen terminada y nunca anima. No anules esto.
  • Los cursores viven en una capa fija de tamaño completo encima de la página (pointer-events: none).
  • Mientras se ejecuta, la biblioteca inserta una superposición justo después de la imagen, dentro del contenedor de la imagen. Si el contenedor era estático, también establece position: relative en él. Ambos se deshacen al final.
    • Dale a la imagen un contenedor de nivel de bloque propio, como un <div> o <figure>. Los contenedores en línea como <a> o <picture> pueden descolocar la superposición.
    • CSS hermano como :last-child o Tailwind space-y-* puede cambiar brevemente mientras la superposición está allí.
  • La imagen se copia como un fondo CSS estirado al cuadro de contenido de la imagen. Los bordes y el relleno en la imagen están bien, pero los recortes de object-fit: cover o contain no se reproducen.
  • Bajo una CSP estricta o Trusted Types no se necesita cambios: la biblioteca construye cada elemento con llamadas DOM, establece estilos a través del CSSOM y usa innerHTML, <style> o script en línea. La URL de la imagen debe estar permitida por img-src.

6. Verificación

  1. Carga la página y observa una construcción completa. Cada recuadro debe aterrizar en un bloque real de la interfaz de la imagen, no en espacio vacío ni atravesando dos bloques.
  2. Comprueba un ancho de teléfono (375 píxeles). Las insignias y etiquetas de nombre tienen un tamaño fijo, por lo que las imágenes muy pequeñas pueden sentirse abarrotadas; usa menos regiones, más grandes allí.
  3. Activa el movimiento reducido en el sistema operativo o en las herramientas de desarrollo del navegador: la imagen debe mostrarse de inmediato, sin cursores.
  4. Revisa la consola en busca de errores y que no queden elementos del enjambre con aria-hidden en el DOM después de que termine.

Skills relacionados