page-swarm-rebuild 是做什麼的?
版本 1.3.0(模組、附加元件、樣式表及本檔案;詳見版本庫中的 CHANGELOG.md;SwarmRebuild.version)。
純展示用的開場效果。頁面的真實 DOM 從未被修改:圖層透過 <head> 中的一個階層式樣式表隱藏和顯示,所有動畫都在一個附加到 <html> 的疊加層中執行,最後兩者都會被移除。無依賴、無網路請求(GDPR 友善)、無版面偏移、無音效,頁面絕不會處於半隱藏狀態(請參閱保護機制)。
原始效果規格(時間軸、視覺效果、HUD、捲動曲線):references/effekt-leiras.md(匈牙利文)。若該檔案與本檔案不一致,以本檔案為準(在規格撰寫後已做出產品決策)。
檔案
| 檔案 | 用途 |
|---|---|
assets/swarm-rebuild.js | 模組,可讀取的原始碼(經典腳本,設定 window.SwarmRebuild;亦可從打包工具匯入)。 |
assets/swarm-rebuild.min.js、swarm-rebuild-debug.min.js、swarm-rebuild.min.css | 為純 HTML 網站建置的最小化版本(scripts/build-min.cjs;安裝程式會使用它們;打包工具則自行最小化原始碼)。 |
assets/swarm-rebuild.css | 疊加層樣式,全部限定在 #swarm-rebuild-root 之下。 |
assets/swarm-rebuild-debug.js | 除錯附加元件:控制列、自動捲動導覽、測試鉤子。永遠不會為訪客載入;僅在 ?rebuild-debug=1 / debug: true 時擷取。無論如何,請將其與模組一同安裝(這是在即時網站上測試的方式)。 |
assets/react/SwarmRebuild.jsx | React / Next.js 客戶端包裝器 + <SwarmRebuildHead />(預繪製片段);除錯附加元件是一個單獨的惰性區塊。 |
assets/demo/ | 虛構的深色作品集示範(assets/demo/index.html,214 個圖層(桌面版),6.6 個視口高度,固定頁首)。 |
tests/index.html | 連結到每種模式下的每個測試頁面(也是 GitHub Pages 的起始頁面)。 |
tests/pages/dental/ | 虛構的牙科診所:淺色主題、電話連結、固定的「致電我們」+ 預約列(行動版)、固定通知(桌面版)。 |
tests/pages/lang-*/ | 虛構的頁面,分別為匈牙利文、阿拉伯文(從右至左)、日文和一個富含表情符號的頁面(任何語言的打字)。 |
tests/pages/law/、accounting/、bootstrap/、spa/ | 虛構的真實世界模式:網頁字型、固定頁首、同意橫幅、iframe、惰性圖片、深色模式、長頁面、捲動揭示、Bootstrap (npm)、單頁應用程式、影片。 |
tests/pages/nextjs/ | 虛構的 Next.js 15 App Router 應用程式:React 計數器(水合檢查)、固定的說明按鈕。 |
scripts/verify.cjs | Playwright 對一個頁面的檢查(請參閱步驟 4)。 |
scripts/run-tests.cjs | 在三種測試頁面上執行 verify.cjs,桌面版和行動版;列印摘要表格。 |
scripts/bench-fps.cjs | 比較舊版模組與當前版本在同一台機器上交錯執行的影格率。 |
scripts/build-site.cjs | 將三個測試頁面建置為一個靜態網站(GitHub Pages)或在本地網路上提供服務。 |
scripts/next-app.cjs | 輔助腳本:在暫存資料夾中準備/建置 Next.js 測試應用程式。 |
scripts/build-min.cjs | 建置 .min 檔案並檢查大小預算(需要 npm 的 terser 和 csso)。 |
scripts/perf.cjs | Lighthouse 指標(LCP、CLS、TBT、速度指數、無障礙性、SEO),分別在有和無效果的情況下。 |
scripts/sync-snippet.cjs | 將模組的 head 片段複製到 React 包裝器、SKILL.md 和測試頁面中。 |
scripts/record-video.cjs | 將效果錄製為 .mp4 / .webm 以用於作品集(除錯導覽,控制列隱藏)。 |
scripts/project.cjs | 將效果安裝到專案中,並在 legacy/ 中備份,然後移除它,最後還原原始檔案。 |
scripts/test-project.cjs | 測試安裝程式:備份、損壞專案後還原(雜湊相同)、解除安裝。 |
產品決策(它們凌駕於參考影片之上)
- 主要模式為
scroll(預設):建置過程跟隨訪客的捲動,且僅建置視口內的內容:一個元素在其至少 60% 的高度進入畫面時開始建置(buildVisible),視口下方或上方不建置任何內容,且工作中的代理永遠不會離開畫面。 - 訪客永遠不會看到控制列,也永遠不會獲得自動捲動。 控制列和導覽存在於除錯附加元件中,僅在
?rebuild-debug=1或debug: true時載入。不帶附加元件的mode: 'tour'會回退到scroll。 - 總有一個無需可見控制項的退出方式: Esc、Tab、Enter、任何其他按鍵(單獨的 Shift/Ctrl/Alt/Meta 除外)以及任何點擊或輕觸都會立即顯示完成的頁面,無動畫且無版面偏移。
prefers-reduced-motion表示完全沒有效果(WCAG 2.2.2)。 - 方向鍵會捲動: 空白鍵、方向鍵、Page Up / Down 以及 Home / End(當焦點在頁面本身,且沒有 Ctrl / Alt / Meta 時)會像滑鼠滾輪一樣驅動建置。在已聚焦的連結、按鈕或欄位上,或帶有修飾鍵時,它們會像其他按鍵一樣結束效果。Tab、Enter 和 Esc 總是結束效果,因此鍵盤使用者在第一次按 Tab 時就能接觸到真實內容(及其焦點順序)。
- 結束效果的點擊絕不會執行訪客未見過的操作: 如果點擊落在尚未完成的內容上(隱藏或仍在建置中),它會被吞沒(
preventDefault+stopPropagation,滑鼠在pointerdown時就已處理,因此不會有焦點、連結或按鈕動作)。如果點擊落在已完成的內容上(可見,且其內部或揭示它的內容沒有仍在進行中的——例如電話連結,從一開始就顯示,或已建置的按鈕),則它會像正常點擊一樣通過,同時效果結束。原因:吞沒所有點擊會使可見的「致電我們」連結在第一次輕觸時失效;讓所有點擊通過則會跟隨訪客從未見過的連結。觸控捲動和捲軸永遠不會結束效果(捲動是驅動建置的方式)。 - 無音效。 模組沒有音訊程式碼。
模式
| 模式 | 速度 | 行為 |
|---|---|---|
scroll(預設) | 3x | 無自動捲動。代理僅建置視口內的內容:一個元素在其至少 buildVisible(60%)的高度進入畫面時開始;比畫面高的元素則在填滿 60% 畫面時開始,因此當它進入時會從上到下建置。視口外不建置任何內容,工作中的代理永遠不會離開視口(比畫面高的框會從畫面邊緣拉回)。快速捲動(滾輪、按鍵、Home / End)後,可見部分會在大約 1-2 秒內填滿:這些圖層會先開始,更多代理會加入(最多比計畫多 8 個),任務執行速度更快。離開視口的內容會立即完成(請參閱保護機制)。 |
fast | 6x | 與 scroll 相同,速度快一倍。 |
tour(僅限除錯) | 1x | 如參考影片所示自動捲動:約圖層數/7 秒,鏡頭跟隨工作前線,在底部以游標環結束。用於錄製和並排檢查。?rebuild-speed=6 提供舊版的「快速」(6 倍速自動捲動,示範頁約 9 秒)。手動捲動會將控制權交給訪客;控制列的 Tour 按鈕可恢復。 |
建置完成後,群集會聚集在焦點元素周圍,疊加層會在 autoExit 秒後消失(3 秒;使用除錯附加元件時為 6 秒,導覽模式下永不消失)。
動作
所有動作預設都很微妙,並透過 motion 設定(請參閱設定);?rebuild-motion=arc:0,... 會關閉部分效果以進行 A/B 測試(需除錯附加元件)。
- 焦點元素(
focus):開場和結尾的群集圍繞它進行。詢問開發者(步驟 1)。在每個階段中,第一個至少有一半在視口內的下列元素會被使用:設定的元素、[data-swarm-focus]、h1、主要按鈕(a.btn、.button、.cta、button[type=submit]...)、標誌;然後是視口中最大的圖片;最後是視口中的一個點。因此,頁面較深處的焦點(例如結尾的呼籲行動)用於結尾,而開場則使用主要標題。 - 群集: 自由代理以 2-4 個大小明顯不同的群集飛行(手機:2 個)。每個代理都會被一個阻尼彈簧拉向其群集中的位置;群集中心圍繞焦點元素在一個橢圓上移動,其半徑會呼吸,速度會變化,因此代理會自行加速和減速,永遠不會在完美的圓圈上執行。開場已經以群集形式開始(對訪客而言持續時間遠不到一秒)。
- 靜止代理(在建置期間,沒有工作的代理):它離開其群集,前往自己在視口中的位置,與每個其他靜止代理至少相距 72 像素(絕不會有重疊的游標叢集),緩慢漂移,並在 1.4 秒後淡出;當它接到下一個任務時,它會在靜止位置淡入。在結尾,所有代理都會回來並圍繞焦點元素聚集在群集中。實測:在 99.6-100% 的影格中,最多有 2 個重疊的靜止游標(1.2:中位數為 6 個,在示範頁上最多 20 個)。
- 結尾: 一個堅硬的、欠阻尼的彈簧(阻尼 0.63,
motion.spring)將每個代理拉向焦點:開始時最快,大約超出其位置 5-20%,然後返回;約 1 秒後彈簧軟化,群集緩慢旋轉。 - 滑鼠(開場和結尾,僅限桌面版;在觸控或減少動畫時從不啟用):靠近指標的代理會移開(指標移動越快則反應越強烈);最多 3 個好奇的代理會在小圓圈上跟隨它,當它靜止時持續 1.3-2 秒,移動越快則時間越短(興趣衰減率為
(1 + 速度 / 220 px/s)倍基礎速率)。永遠不會近於 36 像素(硬性限制,因此圖示絕不重疊);疊加層會忽略指標事件,因此點擊永遠不會受到干擾。 - 重力: 代理會攜帶其工作的元素,因此它前往那裡的路徑(以及攜帶的複製副本)會向下彎曲:下垂量 = 0.2 x 水平距離 x 權重 x 水平度²,權重 = sqrt(面積) / 320 px 限制在 0.2..1,最多 56 像素且不超過水平距離的五分之一。垂直移動幾乎不會彎曲。前往任務的路徑也會從代理當前的速度開始(三次赫米特曲線),因此沒有突然停止或轉彎。
- 難度: 每個任務的工作(而非前往的路徑)會根據元素面積的難度進行縮放(對於打字:根據輸入框面積):接近頁面平均值 2 倍面積 ~ 1.6-1.8 倍時間,經過擠壓(tanh)使得最難的任務最多花費約易任務的 4 倍時間。它會被標準化(按任務長度和難度加權,因為並行任務會使長時間任務決定節奏),因此整個建置時間與之前相同;僅在小型和大型任務之間的分配發生變化。
- 精簡模式(
motion.lite: 'auto'):在手機上為 2 個群集且無滑鼠遊戲;在建置期間影格率持續兩秒低於 38 fps 時,也僅使用一個拖尾幻影而非三個。
語言和書寫方向
模組不假設任何語言。打字以使用者感知的字元(字元簇,使用 Intl.Segmenter,並有一個回退機制來合併組合標記、ZWJ 序列、膚色修飾符、變體選擇器和國旗配對)進行:一個帶重音符的字母、一個表情符號家庭、一面國旗或一個帶阿拉伯/希伯來文標記的字母永遠不會被分割。未輸入的文字會作為隱藏文字留在原地,瀏覽器會跨越該邊界進行字形塑造,因此阿拉伯字母保持其連寫形式,且不會重新排版。從右至左的元素(direction: rtl,例如 `<html dir=