Community图像github.com

habom2310/swarm-build

为网站添加 swarm-build 动画:一群带名字和颜色的光标绘制方框并逐区域构建截图,或逐块重建整个实时页面,如同多人协作设计文件。适用于用户希望英雄图或产品图“自动构建”,页面出现多人协作或 Figma 风格光标,以及提及 swarm-build 时。支持纯 HTML 及任何框架(React、Next.js、Vue、Svelte、Astro)。

swarm-build 是什么?

swarm-build 是一个无依赖的 ES 模块(约 600 行)及可选 CSS 文件,提供两种模式:图像模式和页面模式。图像模式下,空白画布覆盖 <img> 或带 CSS 背景图的元素,每个区域在光标拖出方框并显示实时“宽 × 高”徽章后扫入。页面模式下,标记的页面元素消失,然后光标逐个重建它们;纯文本块(标题、短段落)会以打字效果出现,嵌套块等待父块完成,屏幕外的块会等到滚动到视口再构建,因此群体会跟随读者向下滚动。两种模式结束时光标均消失,库所做的所有更改都会被撤销。该技能支持纯 HTML 及任何框架(React、Next.js、Vue、Svelte、Astro),通过属性标记和 JavaScript 调用实现。适用于希望图片或页面有“构建”动画、多人光标效果或类似 Figma 场景的场景。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/habom2310/swarm-build/tree/HEAD/skills/swarm-build

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

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

预览

来自技能 README

swarm-build preview

文档

swarm-build 是做什么的?

swarm-build 是一个无依赖的 ES 模块(src/swarm-build.js,约 600 行)及一个可选的 CSS 文件(src/swarm-build.css)。 它有两种模式:

  • 图像模式 swarmBuild(img):一个空白画布覆盖 <img>(或带有 CSS background-image 的元素),每个区域在光标拖出其方框并带有实时 宽 × 高 徽章后扫入。
  • 页面模式 swarmBuildPage("[data-swarm-block]"):实时页面中标记的元素消失,然后光标逐个重建它们。纯文本块(标题、短段落)会以打字效果呈现。嵌套在其他块内的块会等待其父块完成。折叠线以下的块会等到它们滚动到视口后再构建,因此群体跟随读者向下滚动。

两种模式中,光标最后都会离开,并且库所做的所有更改都会被撤销。

1. 安装

将 src/swarm-build.js、src/swarm-build.d.ts 和 src/swarm-build.css 从本仓库复制到项目中(例如 lib/swarm-build/),并使用相对路径导入它们。 没有依赖项,也不需要构建步骤。

仅当 npm view swarm-build 显示该包已发布时:npm install swarm-build,然后 import { swarmBuild } from "swarm-build" 和 import "swarm-build/style.css"。

2a. 页面模式:标记块

  1. 阅读页面标记,挑选设计师会绘制的块:导航栏、英雄标题、英雄段落、每个按钮、每个卡片、图表、表格、页脚。一个典型的落地页有 25 到 60 个。
  2. 为每个块添加 data-swarm-block。
    • 标记容器(如一个卡片)及其内部的文本(其标题和段落),以实现“先框架,再填充”。
    • 标记内容为纯文本的标题和短段落:这些会以打字效果出现。包含内联标记(链接、<b>)的元素则会扫入。
    • 跳过仅用于布局的包装器(如网格、没有自己背景的区域)。隐藏它们会同时隐藏内部所有内容。
  3. 不要标记访客需要立即使用的固定或粘性 UI,例如 Cookie 横幅或聊天小部件。
  4. 在内容进入 DOM 后调用:
import { swarmBuildPage } from "./lib/swarm-build/swarm-build.js";
swarmBuildPage("[data-swarm-block]", { speed: 1.5 });

为了在脚本运行前隐藏块(避免完成页面的闪现),还需为每个块添加 data-swarm-pending 并包含 CSS 文件。

2b. 图像模式:选择区域

区域决定构建什么以及按什么顺序构建。 好的区域能让动画看起来有意为之,所以不要跳过此步骤。

  1. 打开图像并观察它(读取图像文件,或截取页面截图)。
  2. 列出设计师会绘制的 6 到 15 个有意义的块:导航栏、页眉、搜索栏、卡片、图表、列表、页脚。
  3. 将每个块写为图像宽度和高度的百分比形式 x y w h(0 到 100)。根据像素尺寸测量:x = left / imageWidth * 100。
  4. 按人们构建屏幕的顺序排列:先 chrome(导航栏、页眉),然后从上到下构建内容。
  5. 留出小间隙。任何区域未覆盖的内容会在最后画布淡出时出现,因此区域不需要覆盖每个像素。

将它们作为 data-swarm-regions="0 0 18 100, 21 3.5 47 5.5, ..." 放在图像上,或在 JavaScript 中传递 regions: [{ x, y, w, h }]。 没有区域时,库会使用通用的侧边栏、页眉和卡片布局,这通常与图像不匹配。

3. 接入

纯 HTML:

<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 或 Next.js(客户端组件):

"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} />;
}

对于 Vue、Svelte 或 Astro,做法相同:挂载后调用 swarmBuild(el),卸载时调用 destroy()。 多个图像(例如 iPad 和手机)可以共享一个群体:swarmBuild([ipadImg, phoneImg])。

4. 选项

选项默认值用途
regions (每个目标)data-swarm-regions,然后通用要构建的内容及顺序
agents6 个内置名称和颜色[{ name, color, text }],匹配网站配色和受众
speed12 将时长减半(对于 10 到 15 个区域,1 时约为 6 到 8 秒)
start"visible""now" 立即开始,而不是等到图像滚动到视口
canvas"#fff"未构建画布的颜色;匹配截图的背景色
zIndex2147483000固定光标层的层叠值;如果模态框或页眉必须保持在上方,请降低此值
onDone无构建完成或调用 finish() 时调用一次
typeSpeed (页面模式)1打字文本的速度;2 打字速度加倍

返回值包含 finished、finish() 和 destroy():

  • finished 是一个始终解决的 Promise,无论群体如何结束。
  • finish() 跳转到完成的图像,并运行 onDone。
  • destroy() 立即移除所有内容,且 onDone 不会运行。在卸载时调用。
  • setSpeed(n) 在运行时更改速度。

在页面模式下,start 默认值为 "now";在图像模式下为 "visible"。

5. 需遵守的规则

  • data-swarm-pending 加上 CSS 文件可以在脚本启动前保持图像隐藏,因此不会先闪现完成状态。如果脚本从未运行,CSS 会在 4 秒后显示图像。当图像是页面的 LCP 元素且加载时间比效果更重要时,请省略该属性。
  • 减少运动(prefers-reduced-motion: reduce)会显示完成的图像并且从不动画。请勿覆盖此设置。
  • 光标位于页面之上的固定、全视口层中(pointer-events: none)。
  • 运行时,库会在图像之后、图像父元素内部插入一个覆盖层。如果父元素是静态定位的,它还会在其上设置 position: relative。两者在结束时都会被撤销。
    • 为图像提供一个独立的块级父元素,例如 <div> 或 <figure>。内联父元素(如 <a> 或 <picture>)可能导致覆盖层位置错乱。
    • 同级 CSS(如 :last-child 或 Tailwind 的 space-y-*)在覆盖层存在时可能会短暂改变。
  • 图像会作为 CSS 背景图复制,拉伸到图像的内容盒。图像的边框和内边距没问题,但 object-fit: cover 或 contain 的裁剪不会被重现。
  • 在严格的 CSP 或 Trusted Types 下无需更改:库通过 DOM 调用构建每个元素,通过 CSSOM 设置样式,不使用 innerHTML、<style> 或内联脚本。图像 URL 必须被 img-src 允许。

6. 验证

  1. 加载页面并观察一次完整的构建。每个方框应落在图像的真正 UI 块上,而不是空白区域或跨越两个块。
  2. 检查手机宽度(375px)。徽章和名称标签是固定大小,因此非常小的图像可能会显得拥挤;在这种情况下,请使用更少、更大的区域。
  3. 在操作系统或浏览器开发者工具中开启减少运动:图像必须立即显示,且没有光标。
  4. 检查控制台是否有错误,并确保完成后 DOM 中没有残留任何 aria-hidden 的群体元素。

相关技能