immersive-3d-site 是做什麼的?
一個讓 3D 即時呈現的頁面,而非 3D 影片。訪客的滾輪就是時間線,游標則是第二台相機。真實文字位於上層,可讀可取;WebGL 畫布則在背後運作。
你交回的東西: 一個包含 BRIEF.md、一個真正的 index.html、旁邊的引擎檔案,以及來自桌面、手機與減少動畫模式的截圖條,還有一份簡短的報告,說明你檢查了什麼以及無法檢查什麼。
這些頁面為何會失敗
大多數「3D 網站」只有一個把戲貫穿全頁:一個旋轉的模型,文字淡入覆蓋其上。到第三個區塊時,訪客已經看過一切,停止滾動。四條規則可以避免此問題:
- 每個章節都要不同。 使用 references/scene-kit.md 中至少四種不同的場景裝置,同一種不要連續出現兩次。
- 只有一個峰值。 其中一個章節是訪客會向朋友描述的時刻。它獲得最大的滾動空間、最佳的場景,並且前面有一個較平靜的章節作為鋪墊。
- 3D 服務於訊息。 每個場景都展示關於主題的真實事物:它的構成、運作方式、給人的感受。純裝飾的場景會被刪除。
- 文字在任何滾動位置都保持可讀。 如果在任何影格中,某行文字難以在場景上閱讀,則移動場景,而非文字。
步驟 0:簡報
重複使用使用者已經提供的內容。如果他們提供了完整簡報或說「由你判斷」,則自行撰寫 BRIEF.md,標註「在創意授權下撰寫」,以品牌口吻回答以下每個問題,然後開始。否則,一次提出全部八個問題,作為真正的問題,而非你編造的選單:
- 這是什麼、為誰而做、他們最後應該做什麼? 一個行動,一個到處使用的一致標籤。
- 用三到五個詞形容感受,加上最多三個來自非網站的參考:一部電影、一款遊戲、一張專輯封面、一家商店。提到網站名稱會導致頁面最終複製它。
- 用他們的話描述旅程: 訪客首先看到什麼、接著看到什麼、最後看到什麼。
- 哪裡應該平靜、哪裡應該猛烈。
- 每個階段訪客應該有什麼感受,以及他們應該記住的唯一瞬間。 參見 references/feel.md。
- 這個網站應該做一件他們見過的任何網站都沒做過的事。 簽名互動的種子。要求一個真正的答案;「令人難忘」不算。
- 距離極簡高級多遠: 提供 references/structures.md 中的範圍。
- 一個連續的世界,還是分開的場景? 最大的結構分支,由他們決定。加上:他們已經擁有的東西(標誌、顏色、字體、產品照片、
.glb格式的 3D 模型)。
在 build 資料夾中撰寫 BRIEF.md,以他們的語言記錄他們的答案,然後加上:
- 旅程: 四到七個節拍,每個節拍都是訪客所知或所感的變化。
- 感受曲線: 每個節拍一行,描述感受以及畫面上什麼引起它。相鄰兩個節拍不能相同。
- 峰值: 訪客會說出的一句話,以及它位於哪個章節。
- 這是那個___的網站: 填入一種體驗,而非技術。
- 簽名互動: 只存在於此網站上的一種互動,寫在頁面程式碼中。一個帶有新數字的套件裝置不算。
- 任何刻意的留白, 標記出來,以便檢查能將其與死滾動區分。
步驟 1:結構、記錄,然後評分
按此順序執行三件事。全部三件事在任何程式碼之前完成。
從 references/structures.md 選取一個結構: 一個世界、章節、產品展示、展覽、遊樂場、帶插入內容的編輯模式、廣播模式。導航、開場和結尾隨之而定。在 BRIEF.md 中說明為何選此結構而非其他。
執行指紋記錄。 閱讀 builds 資料夾中的 FINGERPRINTS.md(如果不存在則建立;初始為空)。計畫必須在至少四個面向與所有現有行不同:結構、導航、英雄裝置、章節順序、結尾、簽名互動。如果失敗,修改計畫,而非修改記錄。
評分。 先感受曲線,然後每個節拍一個裝置,以表格形式放在 BRIEF.md 中:
| 節拍 | 章節 | 感受 | 裝置 | 跨度 | 為何選此裝置 |
|---|---|---|---|---|---|
| 辨識 | 英雄 | 好奇 | 玻璃物件 + 推軌 | 2 | 產品,在閱讀任何文字前,活生生展現 |
| 轉變 | 變形 | 期待 | 粒子變形 | 3 | 雜訊變成形狀,再變成名字 |
| 峰值 | 軌道 | 敬畏 | 相機軌道 | 3.5 | 穿越其中,表示內容豐富 |
| 證明 | 爆炸 | 信任 | 爆炸分解視圖 | 2.5 | 展示零件,這正是宣稱 |
| 承諾 | 結尾 | 平靜 | 平靜停留 | 1.5 | 頁面停止,等待點擊 |
建構前檢查:
- 該結構的禁令必須遵守。
- 使用 references/scene-kit.md 中四個或更多裝置族,同一族不連續出現兩次。
- 相鄰兩個章節的感受不能相同。
- 峰值擁有最大的跨度,且其前一個章節較平靜。
- 結尾是解決並停留,而非淡入頁尾。
- 跨度以螢幕高度為單位。電影感頁面約為 8 到 14 個螢幕高度;編輯式與遊樂場頁面可以更短。切勿為了湊數字而填充。
步驟 2:建構
mkdir -p <build> && cp <skill>/engine/stage.js <skill>/engine/stage.css <build>/
從 templates/starter/index.html 開始取得結構(import map、canvas、區段、一個模組腳本),並借用你評分過的章節模式。絕不交付 starter 或其 Orbis 副本。 每個頁面都根據其自身簡報編寫。
引擎運作方式(engine/stage.js,請閱讀標頭註解):
- 頁面是一個
<section data-act="name" data-span="2">的堆疊。每個區段包含一個.frame,在區段長度內保持固定。 stage.act(name, { scene, camera, update(p, s), render(renderer, s), resize(w, h) })註冊一個場景。p在章節中從 0 到 1 變化。s攜帶time、dt、pointer(平滑處理,-1 到 1)、velocity(滾動速度)、width、height、reduced、coarse。- 哪個章節位於螢幕中央,就渲染哪個。共用同一個
scene物件的章節會一起更新,因此一個連續的世界只需多個章節指向同一個場景。 - 一個章節需要大於 1 的跨度才能讓
p移動。p是根據框架保持固定時的距離測量的,因此跨度恰好為 1 時沒有距離:p從 0 瞬間跳到 1,任何與之綁定的東西永遠不會顯示。請使用 1.25 或更大。 - 每個區段都會取得
--p作為 CSS 變數,因此標題可以與 3D 在同一個時間線上移動。 - 任何元素上的
data-reveal會在進入時淡入;使用style="--i:2"來設定延遲。 - 使用
seg(p, a, b)將一個章節分成多個節拍,並使用ease.inOut及相關函數來塑造它們。 - 無 WebGL:
html.no-webgl會顯示每個章節的.poster。為每個章節提供一個海報(圖片或漸層)。
使用 stage.css 頂部的 token 設定主題(canvas、surface、ink、ink-soft、accent、accent-ink、兩種字體)。切勿為單一專案編輯引擎;特殊行為應寫在頁面自身的腳本中。
Three.js 來自 import map 中固定的 CDN 版本(jsdelivr 上的 [email protected])。保持固定。如果需要更新版本,請選擇至少兩週前的版本,並重新執行檢查。
在撰寫標記之前閱讀 references/design.md,在新增第二個場景之前閱讀 references/performance.md。
步驟 3:驗證
cd <build> && npm i playwright-core # 每個 build 資料夾執行一次;需要安裝 Google Chrome
node <skill>/scripts/serve.mjs --root . --port 4600 &
node <skill>/scripts/shoot.mjs --url http://localhost:4600 --out shots/desktop
node <skill>/scripts/shoot.mjs --url http://localhost:4600 --out shots/phone --width 390 --height 844 --touch
node <skill>/scripts/shoot.mjs --url http://localhost:4600 --out shots/reduced --reduced-motion --positions 0,1
該腳本會滾動每個章節到五個位置,等待平滑處理穩定,截取每個畫面,並寫入 sheet.png。在以下情況會失敗:頁面錯誤、請求失敗、無 WebGL、某個章節未繪製任何內容、以及橫向滾動。通過表示它能夠執行,而非表示狀況良好。
然後開啟每個 sheet.png 並仔細查看。 針對每個章節的每個位置:每一行文字都能閱讀嗎?場景是否展示了節拍所描述的內容?在手機上,是否有任何內容被裁切、遮蓋或太小?峰值看起來像峰值嗎?結尾是否有解決?修正,重新截圖,再次查看。
然後進行感受檢查(references/feel.md):從頭開始滾動頁面,每個章節用一個詞記錄你的感受,然後與 BRIEF.md 中的曲線比較。如果兩者不一致,修正頁面。
清楚說明未涵蓋的內容:無頭 Chrome 以軟體方式繪製 WebGL,因此它報告的幀率並非真實裝置的幀率,也無法告訴你滾動在真實手機上的感受。請使用者在其手機上開啟頁面,然後再宣告完成。
嚴格規則
| 絕對不能 | 應該改用 |
|---|---|
| 整個頁面只用一個場景裝置 | 四個或更多裝置族,同一族不連續出現兩次 |
| 文字嵌入紋理或圖片中 | 在 canvas 上方使用真實 HTML |
| 滾動箭頭、滑鼠圖示或「滾動探索」 | 什麼都不要。英雄區塊本身就夠了 |
| 像 01 / 05 這樣的區段計數器 | 刪除它們 |
| 每個章節都置中對齊的文字 | 變化位置:左、右、置中、分隔、頂、底 |
| 全螢幕暗色疊加層來增加對比 | 只在文字塊後方使用 .scrim |
| 漸層文字、霓虹光暈在字體上 | 用粗細和大小來強調 |
| 虛構的數字或統計數據 | 僅使用來自使用者的真實數據 |
| 視覺複製中的長破折號 | 句號、逗號、冒號 |
| 永不停止的旋轉物件 | 動作跟隨滾輪或游標;靜止時的動作緩慢且微小 |
| 每個區段一個新的 WebGL 渲染器 | 一個 canvas、一個渲染器、多個場景(引擎已做到) |
| 交付 starter 頁面 | 根據其自身簡報編寫頁面 |
| 在結構、記錄和評分存在之前就開始建構 | 步驟 1,全部三件事 |
| 兩個峰值,或沒有峰值 | 一個峰值,擁有最大空間,前一個章節平靜 |
| 一個計畫與先前的建置在三個或更多記錄欄位中相符 | 修改計畫,絕不修改記錄 |
| 不經過步驟 3 就宣告完成 | 執行步驟 3,查看截圖,進行感受檢查 |
輸出
build 資料夾,然後一份簡短報告:使用了哪種結構及其原因、針對每一行的指紋結果、旅程、感受曲線與峰值、評分表格、簽名互動、shoot.mjs 在所有三次執行中的報告、你在截圖上看到的內容及修正了什麼、感受檢查(預期 vs 實際感受),以及你無法檢查的內容。提供本地 URL。然後將此建置的資料行新增到 FINGERPRINTS.md。