# 從企劃、資料到 3D 互動小島

原始參考網站「HEART 政策島」：https://puma.taipei/heart-island

本課以虛構的公共學習島，示範資料與互動架構。原創圖解、教學節錄與獨立範例實測，不是原站操作錄影。

## 執行範例

需 Node.js 22+。將 starter ZIP 解壓後：

```sh
npm ci --ignore-scripts
npm test
npm run check
npm start
```

使用終端顯示的本機 HTTP 網址，預設 http://127.0.0.1:4173 。不要直接雙擊 index.html。Three.js 鎖定 0.186.1，無 build 步驟。

## 00:00｜先理解作品的三個層次

看到一個可以旋轉、點擊、探索的島嶼網站，我們很容易先問：這是用什麼三維技術做的？但要真正做出同一類作品，需要理解三個層次。底層是內容與證據，中層是互動規則，最上層才是三維畫面。這堂課會用一個完全虛構的城市學習島，帶設計師與前端工程師共同規劃。最後你們應該能說清楚：誰來使用網站、資料怎麼整理、點擊如何找到內容，以及怎麼做出第一個可測試的版本。

## 00:38｜哪些是確認，哪些是提案

我們研究的參考網站，從公開程式碼可以確認，它使用原生 JavaScript 模組、Three.js、透視相機、軌道控制器與點選偵測。建物可以由程式組合幾何形狀，政策資料則由 JSON 驅動。我們沒有確認它使用 React、Vue、後台內容管理系統，或任何特定的人工智慧工具。這次也沒有完成原站實際渲染驗證，所以接下來看到的圖形都是教學示意，不是假裝錄到原站的操作。確認過的事實與我們提出的做法，要始終分開。

## 01:21｜先寫網站計畫，再畫城市

第一份產出不是三維模型，而是一頁網站計畫。先列出使用者與任務。例如探索者想知道有哪些公共議題，研究者則想快速找到某一筆資訊與出處。前者適合島嶼探索，後者需要搜尋與清單；不要逼每個人都旋轉城市才能讀內容。接著決定資訊架構：首頁介紹、主題入口、項目摘要、完整說明、來源與更新日期。每個畫面都要回答一個問題：使用者下一步能做什麼？驗收也不要只寫漂亮，要寫可測試的任務，例如第一次使用的人能否找到公共空間主題，開啟一項計畫，並追溯到來源。成功率與花費時間，由實測決定。

## 02:13｜資料不是一大段文章

把政策內容做成互動，關鍵是資料結構。本課的 starter 有三個主題、六個提案、三條關係與三份虛構來源。content 點 JSON 保存主題、項目、關係、來源、有效日期與編輯溯源；layout 點 JSON 另外保存座標與顏色。標題可以修改，識別碼不能任意改。畫面建築只是一種視覺表示，不等於真實建築。來源用 ID 引用，不要四處複製同一段文字。像步行導覽線這筆資料，可以同時產生清單、卡片和建物。座標不寫進政策事實，未來更換場景時，內容就不用重做。注意畫面只是欄位節錄，完整可執行資料請看 starter。

## 03:05｜關係與動畫，不能冒充因果

當你畫出一條線，甚至讓人流或光點沿著線移動，使用者可能以為這是經過證實的影響關係。因此，關係也必須是資料，不能只是美術效果。資料要說明起點、終點、關係類型、證據等級與出處。參考網站的資料包含證據等級，並把標示為未確認、不動畫的關係排除在動畫之外。我們的示範用 evidenceStatus 欄位實作這個原則：兩條 supported 關係可以畫線，一條 pending 關係不畫線，但保留文字說明。所有來源都是虛構教材。沒有資料支持，就不要把流動速度、流量或成功率演成真實統計。示意動畫要標示為示意，模擬要交代假設。即使兩個項目同時發生，也不代表其中一個造成另一個。來源卡必須能指出文件、日期，以及支持的是哪一句主張。

## 04:08｜把資料映射成可重用的場景

開始做三維時，先不要追求完整城市。先做一個島、一種建物、一張卡片。Three.js 負責場景、相機與渲染器；控制器處理旋轉和縮放；幾何工廠把方塊、圓柱與屋頂組成可重用的模型。資料只要指定模型類型與位置，就能建立場景物件。像樹木、窗戶或路燈這種大量重複物件，可以考慮實例化繪製，但不能以為用了實例化就不用測試效能。裝飾、內容物件與互動標記要分層，避免使用者點到不重要的葉子。水面和天空的著色器可以最後再加。先確保內容可讀、操作正確，再追求氛圍。

## 04:59｜一次點擊如何找到政策內容

點擊不是直接把模型變成文章。通常是先把指標位置轉成場景中的射線，由 Raycaster 找到交會的物件。物件保存項目 ID，再利用 ID 查詢資料，更新選取狀態，最後讓卡片和場景同時反映這個狀態。這個流程的重點，是資料、狀態與畫面各自負責一件事。如果模型有多層子物件，要確保命中的子物件能找到所屬項目，不能假設每個三角形都有 ID。搜尋清單也呼叫同一個選取函式。這樣即使使用者不用滑鼠、不看三維畫面，仍然可以開啟相同內容。關閉卡片、清除選取與返回上一個結果，也要明確設計。

## 05:51｜三島最小版本，分四步完成

實作時先安裝 Node 二十二版以上，進入 starter 目錄，依序執行 npm ci 加上 ignore scripts 選項、npm test、npm run check，最後 npm start。開啟伺服器啟動時設定的本機 HTTP 網址，預設是四一七三連接埠，不能直接雙擊檔案。教材鎖定 Three.js 零點一八六點一，與原站觀察的一六零版不同。這不是 React 專案，也沒有 build 步驟。第一步修改 content 與 layout，跑資料驗證。第二步在 app 與 model 做清單、搜尋、日期和共同狀態。第三步在 scene 建三島六棟，接上點擊與高亮。第四步加入兩條有來源的關係線，以及一條不畫線的待確認說明。先跑通內容閉環，再增加美術。工作副本已通過十項測試、四份語法檢查；本次也用實際瀏覽器核對三維點選、拖曳、搜尋、日期與鍵盤操作。真實觸控與完整效能仍待驗收。

## 07:04｜手機、效能與無障礙不是收尾

三維網站最常見的問題，不是模型不夠細，而是手機操作困難、文字太小、載入太久。設計時就要保留二維清單與文字詳情，支援鍵盤焦點、可理解的按鈕名稱，以及減少動態效果的偏好。重要狀態不能只用顏色表示。行動裝置可以降低像素比、減少陰影與裝飾密度，並依實際測試調整。不要為了漂亮開場讓使用者長時間無法閱讀。效能測量至少包含首次可操作的時間、互動時的幀時間，以及重複開關內容後的記憶體變化。測試案例包括搜尋典藏剩一筆，日期二零二四年十二月三十一日剩兩筆，二零二三年底剩零筆。日期只是有效區間篩選，不是歷史狀態回放。三維載入失敗時，內容清單仍應可用。請再用真實瀏覽器驗收三百七十五像素寬度、兩倍縮放、鍵盤、觸控與停用 WebGL。CSS2D 標籤有百分之百縮放限制，文字清單仍是可靠替代。不能把射線數學測試，當成真實點擊已經驗證。

## 08:23｜內容更新也需要工程流程

最後，網站不是發布一次就結束。建立內容欄位規範，讓編輯知道摘要長度、狀態定義、來源要求與誰負責審核。正式發布前，自動檢查重複 ID、找不到的引用、非法狀態與缺少的日期。人工審核則確認文字是否準確、來源是否真的支持主張，以及圖像有沒有造成誤導。初期可以使用版本控制中的 JSON，不一定需要先做後台；資料量和編輯人數增加後，再評估內容管理系統。每次發布都保留可追溯版本，讓修正與回復有依據。政策文字、資料連結和場景表現要一起驗收，不能只看畫面有沒有正常打開。

## 09:14｜練習與團隊交付

接下來請設計師與前端一起完成五份小型交付物：一頁網站計畫、一份資料字典、一張點擊到內容的流程圖、一個三島原型，以及可測試的驗收清單。練習時，故意加入一個缺少來源的項目與一條未確認關係，看看系統能否正確提醒，而不是照樣演出可信的效果。真正值得學習的，不只是把政策變成漂亮的城市，而是讓每個視覺元素都能回到清楚的資料與證據。先把內容和互動做對，再把世界做得精彩。

## 驗證與練習

工作副本通過 10 項測試與四份語法檢查。瀏覽器已核對 3D 點選、拖曳不選取、清單鍵盤、搜尋、日期、pending 關係、減少動態、375px，以及場景模組失敗後文字替代。真實觸控、200% 縮放、讀屏與完整效能仍待驗收。

五份交付：一頁網站計畫、資料字典、互動流程、三島原型、驗收清單。故意加入缺少來源的項目與待確認關係，檢查系統能否提示並避免錯誤連線。

原始 19 份教材另外保存在私人來源庫，未改寫。中文路徑啟動測試的工作副本修正見 ZIP 內 LOCAL-CHANGES.md。
