Shredder Theater
把「刪除檔案」變成一場好看的演出:拖進去 → 碎掉 → 一句話收尾。
產出永遠是一個 HTML 檔案:點兩下就能開,離線可用,手機打開不變形。
Inputs to collect
調用前確認這 4 項,缺省就走預設值,不要為了湊齊資訊反覆追問:
| 項 | 預設 | 說明 |
|---|---|---|
| 收尾文案 | 從 references/message-templates.md 按場景挑一條 | 唯一不能省的項 |
| 氛圍配色 | 從 references/visual-language.md 挑一套 | 使用者給了風格就照做 |
| 互動形態 | 支援真實檔案拖入 + 一個「示範刪除」按鈕 | 按鈕是保底示範路徑 |
| 落地尺寸 | 響應式單頁,手機直式優先 | 用 clamp() + dvh |
- 收尾文案是整個頁面的情緒落點,必須落到具體的一句話。不要寫「已刪除」「操作成功」這類系統提示語。
- 使用者說了對象(「給我媽做的」「發給前任」),稱呼就從使用者給的來,不要自己改成「主人」。
- 使用者沒說文案、只說了「隨便來一個」,按場景選一條最短的,別寫長段落。
Procedure
-
先定文案,再定視覺 文案決定情緒基調,視覺跟著走。反過來做容易得到「好看但沒感覺」的頁面。 從
references/message-templates.md挑文案,從references/visual-language.md挑配色,兩處都要在references/visual-language.md裡記一筆「為什麼這麼搭」,因為收尾句和背景明暗要互相成就。 -
搭五層結構(單檔案 HTML,CSS 和 JS 內聯,不引外部資源)
- 舞台層:背景。深色系用暗角 + 噪點,淺色系用柔和漸變,避免純色大面積平鋪。
- 碎紙機層:用 CSS 畫機身(面板、指示燈、進紙口、滾輪),不要用圖片素材,也不要用 emoji 當主視覺。
- 托盤層:待處理檔案列表。拖真實檔案進來時只取
file.name展示,別讀檔案內容。 圖片類檔案可以用URL.createObjectURL()給一張縮圖——「親眼看著那張圖被碎掉」才是情緒高點; 碎完記得revokeObjectURL()釋放記憶體,縮圖不離開本機。 - 動效層:紙屑粒子。紙被吸入進紙口後,從進紙口下沿噴出碎紙條,每條獨立隨機速度/旋轉/落地延遲。
- 文案層:收尾那句話,最後出現。
-
聲音用 Web Audio 現場合成,不打包音訊檔案
- 機械嗡鳴:鋸齒波 ~70Hz + 低通,白噪聲做撕紙底噪
- 碎紙聲:bandpass 白噪聲短脈衝,每條紙屑落一次,間隔隨機 30–60ms
- 收尾:一聲 sine 叮(880→1320Hz 指數衰減)
- 瀏覽器自動播放策略會攔掉首次播放,必須讓第一次點擊同時解鎖音訊;頁面上給一句「點一下開始」提示。
-
動效用 transform / opacity,別動 layout 屬性 紙被吸入:
scaleY壓縮 +translateY進紙口 + 輕微rotate,約 300ms。 機身震動:高頻小幅translateX抖動,用steps()做出機械頓挫感。 文案出現:fade +scale(0.96 → 1)+ 字距收攏,約 600ms ease-out。 碎紙條:translateY落下 +rotate翻轉 + 透明度衰減,落地後疊成一小堆。 -
自檢再交付(這一步不能省) 用瀏覽器開啟生成的檔案,逐條確認:
- 點一下真的有聲音(不是靜音)
- 紙真的被吸進去、碎紙條真的掉下來
- 文案在碎完之後才出現
- 375px 寬的手機視口下沒有橫向滾動、文案不溢出、中文標題沒有被擠斷成兩行
- 淺色主題下機身和背景能拉開(機器要「立」在背景上,不是浮在背景裡)
- 瀏覽器 console 無報錯、無未捕獲的 Promise 拒絕(
Uncaught (in promise)會讓整場演出在中途靜默死掉) 任何一條不過就改完再交付,別把半成品丟給使用者。
演出流程用
async function編排時,在呼叫處包一層try/catch:出錯時至少要把收尾文案顯示出來 並給出提示,不要讓頁面停在一個「什麼都沒發生」的狀態。 -
交付 給出 HTML 檔案的絕對路徑,並一句話說明:這頁怎麼用(拖檔案進去 / 點示範按鈕)、收尾是什麼。 如果順手截了圖,一併附上。
Output contract
- 一個
.html檔案,自包含:無外部 CSS/JS/字型/圖片依賴,斷網可開 - 文案、配色寫在檔案頂部,便於二次改
- 至少支援兩條路徑:拖真實檔案進來、點按鈕示範
- 不產出 README、設定檔、建置腳本
Failure handling
- 使用者想真的刪檔案:這個 skill 只做演出,不碰磁碟。直說「頁面是模擬的,檔案還在」,不要順手去執行刪除。
- 瀏覽器不響:自動播放策略攔截。需要使用者先點擊頁面;頁面自帶「點一下開始」提示做兜底。
- 演出中途卡住、什麼都不發生:多半是
async演出函式拋錯變成了未捕獲的 Promise 拒絕。 給入口加try/catch,出錯就把收尾文案和一句提示顯示出來,別讓頁面停在半路。 - 檔名很長撐破版面:檔名用
text-overflow: ellipsis截斷,完整名放title屬性裡。 - 行動端溢出:
dvh比vh在行動端瀏覽器更準;長文案用clamp()控字號。 - 深色背景上的字看不清:正文與背景對比度至少拉到 4.5:1,深底配奶白字、淺底配墨色字。
Examples
Input:「做個碎紙機頁面,刪完顯示『主人,已處理完畢』」
Output:單檔案 HTML。深色暖黃檯燈配色,頂部居中放置 CSS 繪製的碎紙機,中部檔案托盤(可拖入真實檔案),底部示範按鈕。點擊後紙被吸入進紙口、機身抖動、Web Audio 合成碎紙聲,紙屑從中段掉落堆積,600ms 後「主人,已處理完畢」淡入並伴隨一聲輕叮。
Input:「想做一個狠一點的,前任發來的檔案全碎掉」
Output:同上結構,但配色切到冷灰工業風,文案換成冷嘲語氣的短句(如「已永久銷毀,不接受複合」),碎紙聲更重、機身震動幅度更大。
Windows (win32) platform notes
- 開啟檔案:
start "" "<path>\file.html"(macOS/Linux:open "<path>/file.html") - 產生檔案路徑用反斜杠-safe 寫法,或在 Python/Node 裡用
path.join;不要在 SKILL.md 正文裡硬編碼/tmp/ - macOS/Linux 下拖拽可用
DataTransfer,Windows 瀏覽器同樣支援;若某瀏覽器禁用了拖拽,保留示範按鈕作為唯一路徑,不要因此報錯