Communitygithub.com

Pryne 前端架構契約

用於新增、編輯、重新排序或審查 Pryne 的 vanilla-JS 示範建置中的 JavaScript 模組或 HTML 結構,或決定互動式程式碼的放置位置。

Pryne 前端架構契約 是什麼?

此技能定義了 Pryne 的 vanilla-JS 建置中關鍵的前端架構契約,特別是其無打包工具、基於 IIFE 的模組系統。它強制執行嚴格的不變量,例如腳本順序作為依賴圖、減少動畫的門控、GSAP 僅作為漸進增強,以及防禦性地隱藏原生功能。該技能詳細說明了模組地圖、CSS 設計標記,並提供了新增模組的核取清單。它支援 Claude Code 等 AI 編碼代理,幫助它們在不破壞架構不變量的情況下進行變更,並指引它們使用相關技能(如 pryne-motion-reference)以進行更具體的任務。參考實作位於 `design-demos/` 目錄中的 `v4-d-hybrid.html` 和 `js/roll-*.js` 檔案。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/prynetopg777/claude-skills-bundle/tree/HEAD/skills/pryne-frontend-architecture

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Pryne 前端架構契約 是做什麼的?

Pryne 的 vanilla-JS 建置中承載結構性決策、它們存在的原因以及你不得破壞的不變量。參考實作:Portfolio(測試)倉儲(~/Documents/Coding Folder/Portfolio (test))中的 design-demos/,現行建置 v4-d-hybrid.html + js/roll-*.js,截至 2026-07-22。

術語,一次定義: IIFE = Immediately Invoked Function Expression(立即呼叫函式運算式),(function () { ... })(); — 一個檔案作用域的閉包,因此除了檔案明確放在共享命名空間上的內容外,不會有任何洩漏。漸進增強 = 頁面在零 JS 增強的情況下完全可用;只有在其依賴項實際載入時,更豐富的行為層才會疊加。Develop-plate = 此專案的畫布藝術作品,在使用者互動時「發展」(從雜訊解析)。

何時不應使用此技能

  • 動畫時序、緩動、編排理論 → pryne-motion-reference
  • 變更是否被允許以及如何門控 → pryne-change-control
  • 某個功能損壞且你正在診斷 → pryne-frontend-debugging
  • 證明變更有效(螢幕截圖、Lighthouse、評分量規) → pryne-validation-and-qa
  • React/Next.js 或任何打包工具專案 — 此契約僅適用於無建置的 vanilla 網站。

模組契約

一個檔案一個關注點。一個檔案一個 IIFE。無打包工具,無匯入。

所有跨模組狀態都位於一個全域命名空間物件上 — 此處為 window.Roll。roll-core.js 建立它並首先載入;每個其他模組都以 const Roll = window.Roll; 開頭,並讀取/寫入其上的屬性(roll-core.js:1-7 明確說明了這一點)。彼此不需要知道的模組改為透過 DOM 事件通訊(例如 roll-scroll.js 分派 roll:launch;roll-contact-sheet.js 監聽 — 請參閱 roll-scroll.js:35-37)。

HTML 中的腳本順序就是依賴圖。 來自 v4-d-hybrid.html:429-437:

roll-core.js → roll-shader.js → roll-field.js → roll-audio.js → roll-cursor.js
→ vendor/lenis.min.js → roll-scroll.js → roll-contact-sheet.js → roll-eggs.js

不變量:未先 grep 找出模組從 Roll 讀取了什麼並確認每個產生者都較早載入,絕不重新排序或插入 <script>。 沒有匯入系統可以拯救你;重新排序會靜默失敗或在載入時拋出錯誤。

grep -n "Roll\.\w*" design-demos/js/<module>.js   # 它讀取/寫入了什麼

GSAP 特意不在該鏈中 — 請參閱不變量 2。

模組地圖(截至 2026-07-22)

檔案一個關注點行數
roll-core.js命名空間、共享狀態、develop-plate 引擎、upgradeMotion192
roll-scroll.js主幹:進入、滾動編排、HUD、主 rAF(requestAnimationFrame)迴圈、Lenis226
roll-field.js背景畫布場域136
roll-shader.jsWebGL 顆粒/光著色器 + canvas-2D 備援133
roll-eggs.js隱藏的人物觸發器(僅低語等級)83
roll-audio.js與滾動速度相關的安靜環境音效79
roll-contact-sheet.js啟動時揭示聯絡表55
roll-cursor.js自訂游標(僅限桌面,由 GSAP 門控)36

新的互動功能?它是一個新的 roll-*.js 檔案(或擁有該關注點之模組中一個清晰劃分的區段),並以依賴位置新增到腳本鏈中 — 而不是 HTML 中的內聯 <script>。

不變量(在程式碼中驗證 — 保持它們為真)

  1. 減少動畫門控每個動畫模組。 Roll.reduced = matchMedia('(prefers-reduced-motion: reduce)').matches(roll-core.js:9)。每個模組都會查詢它:著色器跳過 WebGL(roll-shader.js:90,124),場域跳過其 rAF 迴圈(roll-field.js:125,135),聯絡表提前返回(roll-contact-sheet.js:12),滾動跳過按住以發展的進入和 Lenis(roll-scroll.js:39-40,152),CSS 取消設定 clip-path 轉場(v4-d-hybrid.html:293-295)。任何新的動畫必須檢查 Roll.reduced(JS)或位於減少動畫媒體查詢(CSS)之下。
  2. GSAP 是漸進增強,絕非依賴項。 它從 CDN 以 async 載入,並帶有 SRI 雜湊(v4-d-hybrid.html:440);載入時它呼叫 Roll.upgradeMotion(),該函式會翻轉 Roll.enhanced 並刷新透過 Roll.onMotionReady 註冊的回呼(roll-core.js:10-15,186-191)。如果 GSAP 從未到達,網站必須保持完全正常運作 — 游標、英雄字型和傾斜僅保持基準狀態(roll-cursor.js:34-35,roll-scroll.js:32-33,89,196)。使用 Roll.onMotionReady(fn) 註冊依賴 GSAP 的程式碼;切勿無條件呼叫 gsap.*。
  3. 有風險的視覺接管以防禦方式包裝 — 在重複路徑上,而不僅僅是設定。 自訂游標在三層受到保護,每層都有一個還原捕獲,將 Roll.cursorUpdate 設為空值並移除 .custom-cursor(它隱藏了 OS 游標):設定(roll-cursor.js:9-32,第 32 行的捕獲)、每個事件處理器主體(roll-cursor.js:17-20)以及 pointermove 呼叫站點(roll-core.js:26-29)。任何一點的故障 — 設定時或之後的任何滑鼠移動 — 都會還原 OS 游標(2026-07-22 已修復;檔案標頭中的故障安全契約,roll-cursor.js:1-5)。將此模式應用於任何隱藏/取代原生功能的事物時,也要保護重複路徑,而不僅僅是設定。
  4. clip-path 揭示位於內部包裝器上,從不在 IntersectionObserver 監視的元素上(「concept-C 修正」— 以 v4 概念 C v4-c-ch001.html 命名,它在被帶入 v4-d 之前於此起源)。IO 監視 .panel;clip-path 為 .panel-inner 設定動畫(v4-d-hybrid.html:121-122,185-186)。理由:裁剪被觀察的元素會改變其交集幾何形狀,並且揭示會與觸發器衝突。
  5. 參與驅動的視覺效果根據其自身可見性而非頁面載入進行門控。 功能面板僅在其面板具有 .in 時才發展(roll-scroll.js:204-219);程式碼註解記錄了原始錯誤:面板在任何人滾動到它們之前就完成解析,「靜默地擊敗了『隨著參與而發展』的互動。」v4-d-hybrid.html 的頭部註解稱此修正是技術審計中最高優先級的項目。
  6. WebGL 是明確的並且有備援保護。 上下文建立時使用非預乘 alpha(roll-shader.js:17),每幀明確執行 gl.clear(roll-shader.js:95),僅在 WebGL 有機會後才獲取 2D 上下文 — 一個畫布只能永遠擁有一種上下文類型(roll-shader.js:9-12),並且 webglcontextlost 會靜默失敗,而不是讓渲染迴圈拋出錯誤(roll-shader.js:129-132)。呼叫者使用單一的 Roll.shader.render(t) 進入點,並且永遠不需要知道 GL 與 2D 的區別。
  7. 在 Lenis 下滾動保持原生。 Lenis 是隨附的(js/vendor/lenis.min.js,非 CDN),僅在 !Roll.reduced 時實例化,並保持 window.scrollY 有效 — 這是一個感覺升級,而非滾動劫持(roll-scroll.js:148-152,167)。渲染迴圈像以前一樣讀取 scrollY。

單檔案示範理念 + 設計標記

每個設計變體都是一個自包含的 HTML 檔案(內聯 CSS、共享的 js/ 模組),因此變體可以作為完整工件進行 diff、螢幕截圖和 A/B 測試 — 請參閱 pryne-design-direction-decision。每個檔案中的一個長頭部註解記錄了該變體是什麼以及它承載了哪些審計發現(在編輯前先閱讀它;它是該檔案的本地變更日誌)。

所有顏色、間距和緩動都是 :root 中的 CSS 自訂屬性(v4-d-hybrid.html:50-63):

:root {
  --bg: #0a0a0b;  --accent: #d2232e;  --ink: #f4f3f1;  --dim: #86868c;
  --pad-x: clamp(1.25rem, 6vw, 6rem);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-snap: cubic-bezier(0.16, 1, 0.3, 1);
}

根據 Pryne 的全局規則:在存在標記的地方切勿硬編碼顏色/大小;流體值使用 clamp()。新的動畫必須重用 --ease-out/--ease-snap,除非 pryne-motion-reference 另有說明 — 每個建置使用一種緩動語言。

核取清單:新增模組

  • 新的 roll-*.js(或正確的現有擁有者模組),頂層 IIFE,const Roll = window.Roll;
  • <script> 插入在它從 Roll 讀取的所有內容之後,在讀取它的任何內容之前
  • 檢查 Roll.reduced;GSAP 使用僅在 Roll.onMotionReady 內部
  • 隱藏原生功能的任何事物都使用帶有還原捕獲的 try/catch 包裝
  • 如果由參與驅動,則根據可見性門控;IO 目標 ≠ clip-path 目標
  • 使用標記,而非硬編碼值
  • 然後根據 pryne-validation-and-qa 進行驗證

已知弱點(公開、明確陳述)

  • 無建置步驟:無最小化、無打包;對示範來說可以,但對於生產部署尚未解決。
  • 字型從 Google Fonts CDN 載入(v4-d-hybrid.html:47-48),儘管專案傾向於自託管(在 design-demos/DECISIONS.md 中僅在 Lenis 條目內附帶提及;決策記錄本身早於該檔案;尚未完成)。GSAP 也仍在 CDN 上(固定版本 + SRI)。在「修復」其中任何一個之前,請參閱 pryne-change-control。
  • 無自動化測試 — 驗證僅基於瀏覽器的證據(pryne-validation-and-qa)。
  • 佔位內容:案例研究/簡介尚未最終確定;不要像對待最終版本那樣潤飾文案。

來源與維護

執行 scripts/verify.sh(在此技能的目錄中)以一次性檢查以下所有項目。

基礎於 Portfolio(測試)倉儲的提交 457868a,2026-07-22。在信任易變事實之前請重新驗證:

  • 腳本順序:grep -n "<script" design-demos/v4-d-hybrid.html
  • 行數 / 模組列表:wc -l design-demos/js/*.js
  • 減少動畫覆蓋範圍:grep -rn "Roll.reduced\|prefers-reduced-motion" design-demos/
  • GSAP 仍在 CDN+SRI,字型仍在 CDN:grep -n "cdn.jsdelivr\|fonts.googleapis" design-demos/v4-d-hybrid.html
  • Lenis 仍為隨附:ls design-demos/js/vendor/
  • 現行建置仍是 v4-d:檢查 design-demos/DECISIONS.md 和最新的 git log --oneline

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

相關技能