Communitygithub.com

晾衣繩主視覺

做一個可互動的主視覺:品牌海報印在布上,用木夾晾在繩上,訪客能按壓、拉扯這塊會回彈的真布料。

晾衣繩主視覺 是什麼?

這個技能把網站主視覺做成一條晾衣繩:棉布海報用木夾別住,背景是開闊的天空和飄過的雲。訪客可以把布按出凹痕、抓住並拉開;放手後布會擺動並停穩。這是布料模擬,不是一段預先算好的影片。頁面帶上品牌的色彩、字體、標誌、標題和按鈕,交付為單一 HTML 加一段嵌入程式碼,並檢查對比度與版面。

相容平台✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/lookbkdev/lookbk-skills/tree/HEAD/skills/washing-line-hero

在你喜歡的 AI 中提問

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

說明文件

Washing Line Hero

網站的第一個畫面:頂端是品牌的導覽列與按鈕,旁邊是大型標題(其中一個詞組使用強調色)、一行介紹文字、一或兩個按鈕與一行備註,另一側則是橫跨天空的曬衣繩。繩上掛著一塊由木夾固定的棉布,上面印有品牌自己的海報:名稱、一行小字、兩個大字、規格欄與一個小型長條圖。微風不時吹起布料,雲朵在後方飄移。

這個區塊設計成可觸摸的。將游標移到布料上,指尖會壓出凹陷。按壓並拖曳,布料會跟著你的手移動:拉起一角、折疊到繩子上、朝自己方向拉伸。放手後它會落下、搖晃並恢復靜止。在手機上,手指也能進行相同操作,且按住布料時頁面不會捲動。布料是透過模擬產生的(由拉伸、剪切與彎曲約束連結的粒子網格,以固定 120 Hz 頻率更新),因此無論從何處抓取,它都會像真實織物般反應,而非播放預錄動畫。

你可以在 hero.json 中描述英雄區塊與印刷內容。建置腳本會檢查所有項目,並輸出 out/index.html(單一檔案形式的完整頁面)與 out/embed.html(可貼到現有網站中的區段)。由於模擬從靜止狀態開始以固定時間步長執行,record.mjs 可以逐幀驅動它:在影片中,一個繪製的游標會拉起一角、鬆開,然後用指尖橫掃布料,因此影片能展示訪客可進行的操作,且在任何機器上都相同。

它不是什麼:布料不會撕裂、自體交纏或從繩上吹落(沒有自碰撞,因此若用力摺疊使其穿過自身,它會穿過並落回),且印刷內容是由頁面根據你提供的文字繪製,而非上傳的照片。

你需要準備

  • Node.js 18 或更新版本。無需安裝其他套件。
  • Chrome、Chromium 或 Edge,用於檢查與錄製(腳本會自動尋找;若找不到請設定 CHROME_PATH)。
  • ffmpeg,用於影片處理(brew install ffmpeg、winget install ffmpeg、apt install ffmpeg;或設定 FFMPEG_PATH)。
  • 頁面開啟時需有網路連線:three.js 與字型會從 jsDelivr 載入,使用固定版本與完整性雜湊。若無網路,訪客會看到靜態圖片(相同的繩子與布料,平面繪製)與系統字型;頁面仍會正常運作。

此技能的資料夾為此 SKILL.md 所在的資料夾(以下簡稱 <skill>)。

步驟

1. 收集品牌與文案

詢問對方,或從他們現有的網站上找出:

  • 名稱,以及 Logo 的 SVG 檔案(接近正方形;需為純 SVG,不含腳本)。如果沒有,最多三個字母可組成字母組合標誌。
  • 顏色:背景色(同時也是地平線的天空顏色,文字顏色必須與它達到 7:1 對比度)與一個強調色。淺藍色會產生正午天空搭配深色文字;深藍色或紫褐色會產生黃昏天空搭配淺色文字與低掛的溫暖太陽。
  • 字型:一個用於標題與布料上大字的顯示字型,以及一個用於其他文字的字型。這些會載入固定版本並驗證:Space Grotesk、Inter、Instrument Sans、Instrument Serif、DM Sans、Manrope、Fraunces、Sora、Outfit、Bricolage Grotesque、IBM Plex Sans、JetBrains Mono、Plus Jakarta Sans、Newsreader、Playfair Display。其他 Google Fonts 系列也可使用,但不會固定版本。
  • 頁面上的文字:一個包含數個詞的標題(其中一個詞組使用顏色)、一兩句說明用途與目標受眾的句子、主要按鈕與可選的第二個按鈕(含連結)、最多五個導覽連結與導覽列中的按鈕。標題上方的小型徽章與按鈕下方的備註為選填。
  • 布料上的文字:頂部印刷的名稱(通常是產品與版本)、下方的一行小字、兩到四個大字(兩行最易閱讀)、最多六個簡短規格配對(標籤與數值)、圖表的標題,以及角落的網址。

每個名稱、數字、宣稱與日期都必須來自對方。不要自行發明規格或數據;寧可省略某個規格。圖表的長條是依據種子繪製的裝飾,並非實際數據:請為它提供一個不宣稱數字的標題,或者將其關閉。

2. 撰寫 hero.json

複製較接近的範例資料夾並取代所有內容:examples/paperwind/(筆記應用、淺色正午天空、四個 peg)或 examples/halden/(亞麻品牌、黃昏天空、三個 peg、較接近正方形的布料)。

欄位說明限制
brand.name、brand.href左上角的名稱及其連結(預設為 /)28
brand.logohero.json 旁邊的 .svg 檔案,會內嵌到頁面中;或最多 3 個字母作為字母組合標誌–
nav[]最多 5 個 { "label", "href" },顯示在導覽列中(在手機上隱藏)18
action右上角的按鈕 { "label", "href" };設為 false 則不顯示22
hero.badge標題上方的一行小型大寫文字40
hero.title標題。*詞組* 會以強調色顯示;\n 可換行(最多 3 行)72
hero.lede說明用途與目標受眾。可使用行內 Markdown:code、連結、粗體、斜體220
hero.actions[]1 或 2 個 { "label", "href" }:第一個是帶箭頭的實心主要按鈕,第二個是外框按鈕26
hero.note按鈕下方的一行小字90
hero.alignleft(繩子與布料在右側,預設值)或 right(鏡像)。center 會將布料放在文案後方;不建議使用–
theme.background、theme.ink、theme.accent十六進位顏色。ink 必須與 background 達到 7:1 對比度–
theme.modelight 或 dark;若未指定,會根據背景色自動判斷–
theme.fonts{ "display", "body", "weight" }:字型系列名稱(設為 false 表示使用系統字型)與標題字重,範圍 300–800(預設 500)–
theme.scrim0–1:文案後方天空淡化為背景色的強度。預設 0.3–
effect天空、繩子與布料,如下所述–
motion.speed0.25–2,預設 1:所有動畫的速度–
motion.pointertrue(預設值)–
meta用於搜尋與連結預覽的 title(70)與 description(170);url 與 image(完整的 https 網址)、lang(預設 en)–

印刷內容(effect):至少需要 printTitle 或 printHeadline。

設定限制預設值說明
printTitle28 個字元無印刷內容頂部的名稱
printLine64 個字元無名稱下方的一行小字
printHeadline48 個字元無大字;\n 可換行。文字會自動縮小以符合欄寬
printSpecs0 到 6 個 { "label", "value" },分別限制 12 與 14 個字元無右側的規格欄;標籤以大寫印刷
printCharttrue / falsetrue規格下方的小型長條圖,最高長條使用 theme.accent
printChartLabel32 個字元無圖表下方的標題
printFoot40 個字元無底部角落的小字,例如網址
cloth顏色#ecebe6布料的顏色
printInk顏色#15181d印刷文字顏色。必須與 cloth 達到 7:1 對比度

場景(effect),所有設定皆為選填:

設定範圍預設值作用
seed1–99997決定雲朵與圖表長條的隨機種子
skyTop顏色淺色為 #5f9be0,深色為背景色加深英雄區塊頂部的天空顏色
skyBottom顏色theme.background地平線處的天空顏色
clouds0–10.6天空被雲朵覆蓋的比例;0 為晴天
cloudColor顏色淺色為白色,深色為柔和的紫灰色雲朵的顏色
drift0–10.35雲朵飄移的速度
lightday、dusk淺色為 day,深色為 dusk正午太陽從上方照射,或低掛的溫暖太陽與冷色天空光
aspect0.8–1.71.35布料的寬高比
pegs2–64頂部邊緣的木夾數量
peg顏色#c39a64木夾的顏色
rope顏色淺色為 #6f6a62,深色為 #cfc6b8繩子的顏色
breeze0–10.45微風吹起布料的強度
weave0–10.5近距離下平紋織法的可見度
poke0–11游標下凹陷的深度;設為 0 可關閉
dragtrue / falsetrue允許訪客抓取並拉動布料
size0.6–10.76布料佔據文案旁空間的比例(需預留拉動空間)
hint40 個字元"Press it · pull it · let go"寬螢幕畫面中右下角的提示文字,告訴訪客可以觸摸;" · " 分隔各部分;留空則不顯示

撰寫提示:頁面上的標題與布料上的大字應傳達不同內容;布料看起來像一張海報,因此文字應簡潔且大。兩到三個規格配對比六個更容易閱讀。如果品牌有與輕盈、飛行、晾乾或懸掛相關的俏皮標語,布料是放置它的好地方。

3. 建置

node <skill>/scripts/build.mjs hero.json out

它會一次性列出 hero.json 中的所有問題(缺少欄位、文字超過限制、設定超出範圍、顏色對比不足、布料上印刷顏色太淡等),並在修正前不會寫入任何檔案。接著它會列印所使用的設定以及需要注意的事項,例如為了讓標題達到 4.5:1 對比度而加深的強調色。

它會輸出 out/index.html(內嵌 CSS、腳本、Logo 與靜態圖片)、out/embed.html 與 out/assets/logo.svg(分頁圖示)。

4. 檢查

node <skill>/scripts/check.mjs out/index.html

它會在 390、768、1024 與 1440 像素寬度下載入頁面,並在各個寬度下顯示 ok:沒有任何元素超出畫面或被裁切、每行文字與背景天空的對比度皆可閱讀、每個連結與按鈕都有名稱、一個 h1。標示 · 的行需要檢查但不會導致檢查失敗。

5. 觀看並觸摸

node <skill>/scripts/record.mjs out/index.html --still 1.6 --size 1440x900
node <skill>/scripts/record.mjs out/index.html --still 3.5 --size 1440x900
node <skill>/scripts/record.mjs out/index.html --still 1.6 --size 390x844 --scale 2
node <skill>/scripts/screenshot.mjs out/index.html

第一張是布料靜止狀態,第二張是拉動中(腳本控制的手拉起一角),第三張是手機畫面。檢查它們:布料是否完整顯示且周圍有適當空間、印刷文字是否清晰可讀、木夾是否正確掛在繩上?screenshot.mjs 會在沒有 GPU 的情況下執行 Chrome,因此它會顯示訪客在沒有 WebGL 或網路失敗時看到的靜態圖片(位於 out/screens/ 中);檢查它是否也清晰可讀。

然後在瀏覽器中打開 out/index.html 並試玩:懸停、按壓、將一角拉過繩子、放手。在手機上用手指拖曳布料,並確認在布料旁邊滑動時頁面仍可正常捲動。

6. 錄製影片

node <skill>/scripts/record.mjs out/index.html --seconds 10

它會以 30 fps、1920×1080 解析度逐步驅動英雄區塊 10 秒,並輸出 out/preview.mp4 與 out/poster.png(3.5 秒處的幀,布料正被拉起)。在影片中,一個繪製的游標會在 2.2 秒時抓住布料下角、朝你拉起、在 4.4 秒時鬆開,然後從 6 秒開始用指尖橫掃布料。選項:--size 1080x1350(直向)、--size 1080x1920、--fps 60、--poster 1.6。只要錄製從 0 開始(它總是如此),所有機器的幀都相同。

7. 上線

  • 作為頁面:將 out/index.html 與 out/assets/ 上傳至任何靜態主機(Cloudflare Pages、Netlify、Vercel、GitHub Pages、S3)。使用 out/poster.png(或它的 1200×630 裁切版本)作為 meta.image,並與網站一起上傳。
  • 嵌入現有網站:將 out/embed.html 貼到英雄區塊應出現的位置。所有內容都限定在 #mh-washing-line 範圍內;如果你願意,可以將字型 <link> 移到 <head> 中。如果網站已有 <script type="importmap">,請將嵌入的 imports 與 integrity 項目合併進去。此區塊預設為全視窗高度;可在它上面設定 --mh-height(例如 style="--mh-height:760px")來縮小高度。在 React 或其他框架中,將標記放在元件內,並將 <script> 標籤放在頁面中,或使用 iframe 渲染。
  • 若要更改印刷內容,請編輯 hero.json 並重新建置。

疑難排解

  • build: fix hero.json first:每行都會指出需要修改的欄位與修改方式;顏色問題會建議一個可用的顏色。
  • 布料在邊緣被裁切:降低 size,或讓布料更接近正方形(aspect 接近 1)。
  • 布料上的大字太小:它們會自動縮小以符合規格欄的寬度。使用較少的文字、加入 \n,或減少規格與圖表(文字會佔滿整個寬度)。
  • 布料無法靜止,或晃動過大:降低 breeze。
  • 凹陷太強或太弱:調整 poke(設為 0 可關閉凹陷;拖曳功能仍可運作)。
  • record: the effect didn't start:頁面已降級為靜態圖片:Chrome 無法從 jsDelivr 載入 three.js(請檢查網路連線或代理設定),或沒有 WebGL。
  • ffmpeg not found:請安裝 ffmpeg 或設定 FFMPEG_PATH。
  • 訪客看到靜態布料:他們的瀏覽器關閉了 WebGL,或 CDN 被封鎖(顯示平面圖片),或者他們要求減少動畫(顯示一幀靜止的即時布料,不會移動)。這是設計使然。
  • 在手機上頁面無法捲動:它只會在一根手指按住布料時停止捲動;在布料旁邊滑動即可。如果布料填滿手機螢幕,請降低 size。

檔案

  • scripts/build.mjs、scripts/record.mjs:你需要執行的腳本。它們會呼叫 Motion Heroes 套件。
  • scripts/kit/:所有 Motion Heroes 技能共用的套件:建置與檢查(build.mjs)、區塊的 CSS(shell.css)、瀏覽器執行時期(runtime.js:時鐘、暫停、像素比、減少動畫、備援)、錄製器(record.mjs、cdp.mjs)、固定的 three.js 與字型(three.json、fonts.json)以及 KIT.md(說明文件)。
  • scripts/effect/:曬衣繩本身:effect.mjs(設定、檢查與靜態圖片)、effect.js(天空著色器、布料模擬與渲染)、composition.md(說明場景編排的文件)、record.mjs(指定錄製步驟)、screenshot.mjs(靜態截圖)、wasm/(模擬引擎的 WebAssembly 二進位檔案)、font.css(字型載入)。

Individual skills in this repo

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

相關技能