SONIC|吳相勲

網站幕後・1 分鐘短片

從 ASCII 鯊魚
到部落格錦鯉池

ascii-sharks 是 GitHub 上公開的開源動畫,用 ASCII 字元在畫面上畫出海洋:小魚成群游動,鯊魚在魚群中獵食。我們請 coding agent 讀懂這份程式,把鯊魚改寫成五種錦鯉,放進 Sonic 部落格的首頁。這支短片從原版開始,拍到實際網站上的錦鯉互動,再實際操作篩選、搜尋與閱讀文章。

  • 片長 1 分鐘
  • 1080p
  • 原創合成配樂
  • 原始專案 MIT 授權
0:00 / 1:00

錦鯉互動段落以 3 倍速播放,畫面左下角有標示,其餘段落都是實際速度。

下載高畫質原檔(MP4,約 48 MB)

原始專案:stackedlol/ascii-sharks

原版是用 TypeScript 寫成的海洋動畫,不依賴任何外部套件,以 MIT 授權公開。錦鯉池的程式改寫自這個專案,檔案開頭保留原作者的授權聲明。

stackedlol/ascii-sharks

“Fish and sharks drawn as ASCII on a canvas. Zero dependencies.”

用 ASCII 字元在畫布上畫出魚群與鯊魚,不需要任何相依套件。

// 原版:一隻雙髻鯊
new OceanEngine(canvas, [{ kind: "hammerhead", size: 1 }]);

// Blog 首頁:五種錦鯉
new OceanEngine(canvas, roster, {
  koi: true, cell: 9, theme, avoid,
  ignoreReducedMotion: true,
});
作者
drewdi(GitHub 帳號 stackedlol)
授權
MIT
語言
TypeScript,以 Vite 開發
內容
8 種鯊魚造型、成群的小魚、滑鼠與點擊互動

錦鯉池改了什麼

項目原版 ascii-sharksBlog 首頁的錦鯉池
角色鯊魚在魚群中獵食紅白、大正三色、昭和三色、黃金、淺黃五種錦鯉,不獵食,會吃飼料
水面黑色海面Blog 的紙色水面與淡色格線,顏色取自網站的紙色與墨色
滑鼠靠近時小魚散開,點擊濺起水花滑鼠停住不動時錦鯉游過來,點擊水面撒下飼料
文字畫面上沒有文字遇到標題、引言等文字會轉開;有底色的區塊,例如訂閱欄與最新文章,錦鯉可以從下面游過
繪圖每次更新畫面都重畫,捲出畫面就暫停模擬每秒 60 步,畫面每兩格畫一次(30 fps),捲出畫面一樣暫停
減少動態效果系統開啟這項設定時停止動畫依 2026 年 11 月 14 日的決定,一律自動播放
載入Vite 開發專案,多個 TypeScript 檔案打包成單一檔案 components/koi-pond/koi-pond.js,gzip 壓縮後約 21 KB,以 module 延後執行

改動時的注意事項

錦鯉池已經用在個人網站首頁、Works 作品索引與 Blog 首頁。之後要調整錦鯉、換造型,或是引用原始專案的新版本,請先確認以下幾點。

  1. 1

    保留授權聲明

    koi-pond.js 檔案開頭保留原作者的 MIT 授權全文,對外介紹時註明改寫自 stackedlol/ascii-sharks。之後若引用原始專案的新版本,同樣要保留授權聲明。

  2. 2

    引擎只有一份,三頁一起換版本號

    三個頁面都載入 components/koi-pond/koi-pond.js?v=20261114a。修改引擎之後,三頁的 ?v= 要改成同一個新值,否則瀏覽器會繼續使用快取裡的舊版。GitHub 上的「Check Blog home for CMS」檢查也會比對三頁的版本號是否一致。

  3. 3

    各頁自己設定要避開的文字

    錦鯉遇到 avoid 清單裡的元素會轉開,每一頁的清單不同,Blog 首頁是標題、引言與「最新文章」這一列。在水面上新增沒有底色的文字時,要加進該頁的清單;有底色的區塊不用加入,錦鯉會從下面游過。

  4. 4

    Blog 首頁也是 CMS 發文的對象

    CMS 發文時會直接改寫 share/blog/index.html。調整錦鯉的設定時,不要動到發文插入點、#postGrid 與文章區塊的結構、SEO 區段與 </head>。改完在 repo 根目錄執行 scripts/blog-home/check_blog_home.py,推送或開 PR 時 GitHub 也會自動再檢查一次。

  5. 5

    維持延後執行

    錦鯉用 <script type="module"> 載入,網頁文字先顯示,錦鯉才開始執行。不要改成一般的同步 script,也不要在錦鯉載入之前把頁面內容藏起來。

  6. 6

    改之前先在手機量測

    手機 Lighthouse 實測時,有錦鯉是 39 分與 47 分,擋掉錦鯉是 48 分;在節流的手機環境下,錦鯉約增加 0.5 至 1.7 秒的主執行緒阻塞時間。要增加小魚數量、造型或效果之前,先在手機量測一次。

  7. 7

    減少動態效果的設定

    目前設定 ignoreReducedMotion: true,錦鯉不跟隨系統的「減少動態效果」設定,一律自動播放。原版在這項設定下會停止動畫,日後若要改回,拿掉這個選項即可。

  8. 8

    共用檔案要登記部署清單

    components/koi-pond/ 是由部署流程複製到網站的共用資料夾。新增共用資料夾或搬動路徑時,要登記在 .github/scripts/pages-overlay.json,正式網站才會有這些檔案。

影片的資料與製作說明

  • 片中的數字都是實測值:錦鯉引擎以 gzip 壓縮後約 21 KB(網站實際傳輸 21,328 bytes),沒有外部相依套件;桌機 Lighthouse 兩次量測的版面位移(CLS)都是 0;畫面每秒繪製 30 格,捲出畫面就暫停。
  • 錦鯉實際的游速約每秒 20 像素,片中的互動段落以 3 倍速播放,並在畫面上標示。點進文章時,畫面停在原頁的時間,依實測的新頁首次顯示時間(約 0.3 秒)呈現。
  • 網站畫面是以 Playwright 開啟 537sonic.cc 的實際頁面逐格截圖,再用 FFmpeg 剪接。拍攝時擋掉 Google Analytics,不影響網站的流量統計。
  • 配樂是以程式合成的原創電子音樂,沒有使用取樣或現成曲目。
  • 原版畫面取自 stackedlol/ascii-sharks(MIT 授權,作者 drewdi)。
影片字幕全文
  1. ascii-sharks:用 ASCII 字元畫出的海洋動畫
  2. 放大來看,每一格都是一個字元
  3. 滑鼠靠近,小魚會散開
  4. 點一下,水面濺起水花
  5. 交給 coding agent:讀懂、改寫、嵌入
  6. 讀懂原本的模擬與繪圖程式
  7. 把鯊魚改成五種錦鯉
  8. 黑色海面,換成網頁的紙色水面
  9. 嵌進 Blog 首頁,跟文章放在一起
  10. 537sonic.cc/Sonic 部落格
  11. 錦鯉程式延後執行,不擋住文字顯示
  12. 滑鼠停著不動,錦鯉會游過來
  13. 點一下水面,撒下飼料
  14. 遇到文字會轉開,不擋住閱讀
  15. 往下捲,421 篇文章都在
  16. 依主題篩選
  17. 搜尋
  18. 點進文章,閱讀照常
  19. 輕巧,也不干擾閱讀:約 21 KB、0 個外部相依套件、版面位移 0(桌機實測)、30 fps 且捲出畫面就暫停
  20. Sonic 部落格|537sonic.cc/share/blog