Community影像github.com

habom2310/swarm-build

將 swarm-build 動畫加入網站,模擬多人協作時的光標,逐一繪製出區塊來建構圖片或頁面元素,適用於想要「產品圖自動組裝」、多人協作風格游標或英雄區域動畫的情境。

swarm-build 是什麼?

swarm-build 是一個輕量、無依賴的 JavaScript 模組(約 600 行),提供兩種模式:圖片模式與頁面模式。圖片模式下,它會在 `<img>` 或具有 CSS `background-image` 的元素上覆蓋一層空白畫布,然後由多個命名且帶顏色的游標逐一拖曳出區域並顯示即時的 `W × H` 標籤,最後完成整張圖片的構建。頁面模式則會讓標記了 `data-swarm-block` 的頁面元素先消失,再讓游標依序重建它們;純文字區塊(如標題、短段落)會以打字機方式出現,巢狀區塊會等待上層區塊完成,而折疊區域則會隨著讀者滾動而逐一構建。兩種模式結束後游標都會離開,且函式庫所做的所有變更都會被還原。此技能支援純 HTML 以及 React、Next.js、Vue、Svelte、Astro 等框架,並提供豐富的選項(如速度、區域設定、代理游標名稱與顏色、開始時機等),也尊重使用者的減少動畫設定(`prefers-reduced-motion`)。它的設計注重可控性與可驗證性,開發者可以透過 `finish()`、`destroy()`、`setSpeed()` 等方法控制動畫流程,並確保與 CSP、Trusted Types 相容,不會破壞頁面既有結構。

相容平台~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 的元素)上,每個區域會先由游標拖曳出一個方框,並顯示即時的 W × H 標籤,然後該區域才掃入顯現。
  • 頁面模式,swarmBuildPage("[data-swarm-block]"):標記的頁面元素先消失,然後游標逐一重建它們。純文字區塊(標題、短段落)會以打字機方式輸入。巢狀在其他區塊內的區塊會等待其父區塊完成。折疊以下的區塊會等到它們滾入視野才開始,因此 swarm 會跟隨讀者向下移動。

兩種模式結束後,游標都會離開,函式庫所做的所有變更都會被還原。

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. 閱讀頁面的 markup,挑選設計師會繪製的區塊:導覽列、英雄區標題、英雄區段落、每個按鈕、每張卡片、圖表、表格、頁尾。一個典型的登陸頁面約有 25 到 60 個區塊。
  2. 為每個區塊加上 data-swarm-block。
    • 標記容器(如卡片)及其內部的文字(標題和段落),以達到「先畫框架,再填入內容」的效果。
    • 標記內容為純文字的標題和短段落:這些會以打字機方式輸入。包含行內標記(如連結、<b>)的元素則會以掃入方式顯現。
    • 跳過僅用於佈局的包裝器(如網格、沒有自己背景的區段)。隱藏它們會同時隱藏內部所有內容。
  3. 不要標記訪客需要立即使用的固定或黏性 UI,例如 Cookie 橫幅或聊天 widget。
  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. 將每個區塊寫為相對於圖片寬度和高度的百分比(0 到 100)的 x y w h。從像素尺寸測量: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 和一支手機)可以共用一個 swarm:swarmBuild([ipadImg, phoneImg])。

4. 選項

選項預設值用途
regions(每個目標)data-swarm-regions,然後通用要建構的內容及順序
agents6 個內建名稱和顏色[{ name, color, text }],匹配網站的色調和受眾
speed12 將持續時間減半(10 到 15 個區域時,約 6 到 8 秒)
start"visible""now" 立即開始,而不是等到圖片滾入視野
canvas"#fff"未建構畫布的顏色;與截圖的背景色匹配
zIndex2147483000固定游標層的堆疊順序;如果 modal 或頁首必須保持在頂層,則降低它
onDone無建構完成或呼叫 finish() 時呼叫一次
typeSpeed(頁面模式)1打字文字的速度;2 打字速度加倍

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

  • finished 是一個始終會 resolve 的 Promise,無論 swarm 如何結束。
  • 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> 可能會導致疊加層錯位。
    • 像 :last-child 或 Tailwind space-y-* 這類相鄰 CSS 可能會在疊加層存在時短暫改變。
  • 圖片會以 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 的 swarm 元素。

相關技能