最近我做了個挺有意思的小實驗。
我把一個二次元角色的小動畫效果,分別用:

  • WebGL
  • Canvas 2D
  • 純 DOM + CSS

實現了三遍。
效果本身不複雜:

  • 眨眼
  • 眉毛/下眼皮聯動
  • 流汗輕微飄動
  • 呆毛甩動

但真正有意思的,其實不是「做出來」。
而是:

同一個東西,用三種技術棧實現時,到底會差多少?

本質上就是一次「前端圖形學味很濃」的復刻實驗。


一開始只是想復刻一個呆毛動畫

靈感來源:https://tamanidamani.itch.io/nijikas-ahoge
我當時想法特別簡單:「如果是我,要怎麼實現?」
然後越做越上頭。最後直接演變成:

那我乾脆把 WebGL、Canvas2D、DOM 三種方案都做一遍算了。

於是倉庫就變成了現在這樣:

三個版本同效果實現。


先說結論

如果只讓我說一句話:

WebGL 最強,但 Canvas2D 最舒服,DOM 最適合業務


1. WebGL 版本:最像「真正遊戲開發」

這個版本是最折騰的。
因為它本質上已經不是「前端動畫」了, 而是:GPU 圖形編程


它到底怎麼實現的?

核心思路其實就是:

  • 底圖一層
  • 精靈圖一層層貼
  • shader 控制繪製
  • JS 驅動動畫參數

比如:

  • 呆毛旋轉
  • 眨眼裁剪
  • alpha 混合

這些其實都在 GPU 那邊做。
你會開始接觸:

  • uniform
  • texture
  • shader
  • UV
  • 頂點座標
  • 紋理座標

然後人會逐漸失去笑容。


但 WebGL 真強

當元素一多的時候, WebGL 那種: 「完全不慌」 的感覺特別明顯。
尤其是:

  • 高解析度
  • 多層貼圖
  • shader 特效
  • 粒子
  • 後處理

這種場景。
Canvas2D 會開始喘。
DOM 會開始卡。
WebGL 還在: 「繼續上強度。」


但它的開發體驗……

只能說:非常硬核。
你隨便一個東西:「為什麼貼圖反了?」 你都可能查半小時。
因為:

  • 座標系不一樣
  • UV 方向不一樣
  • 紋理原點不一樣

甚至:**你 shader 寫錯一個變數名,頁面可能直接黑屏。**然後控制台一句人都沒有。


2. Canvas2D:寫起來最爽的版本

因為它屬於:「複雜度剛剛好」。

drawImage 真的是神器

整個版本核心基本就是: ctx.drawImage(...)
不停畫。不停疊。不停裁剪。


眨眼怎麼實現?

這裡我其實挺喜歡。
不是直接縮放,而是:**從上往下裁剪源圖。**然後底邊固定。
這樣會更像真正的「閉眼」, 而不是簡單的貼圖壓縮。
這種小細節其實特別影響觀感。


呆毛怎麼做?

Canvas2D 做旋轉特別經典:

save()
translate()
rotate()
drawImage()
restore()

圍繞左下角支點轉。
完事。整個思路非常直覺。


為什麼我覺得 Canvas2D 是甜點區

因為它有一種:「既能做效果,又不用掉頭髮」 的平衡感。
不像 WebGL:你還沒開始做動畫,先被 shader 教做人。
但又不像 DOM:做到後面會開始和瀏覽器佈局系統打架。
Canvas2D 基本屬於:

  • 好除錯
  • 瀏覽器相容性強
  • 思維負擔小
  • 足夠自由

所以很多獨立小遊戲特別愛它,真不是沒原因。


3. DOM 版本:最不像「圖形編程」的版本

這個版本其實最有意思,因為它完全不依賴 canvas。
純:

  • HTML
  • CSS
  • JS

硬做。


五官全是 div

比如:

  • 眼睛
  • 眉毛
  • 汗滴

本質都是:<div> 然後:

  • background-position
  • background-size

從 atlas 裡裁。


合眼實現特別像 UI 技巧

這個方案我自己還挺喜歡。
用了: overflow: hidden; 做 mask。
然後裡面那個 sprite 往下移動,這樣就實現了:「從上往下閉眼」。


DOM 的最大優點

特別適合:真網頁。
比如:

  • UI 系統
  • 按鈕
  • 文字
  • 響應式佈局

都能無縫融合。


但 DOM 真的會越來越重

尤其元素一多:

  • layout
  • repaint
  • composite

瀏覽器開始瘋狂 recalculation。
然後你會發現:自己正在用 CSS 做半個遊戲引擎。


三種方案到底怎麼選?

其實沒有「誰秒誰」。
只有:你當前項目更像什麼。

如果你要:

  • 做複雜視覺特效 WebGL
  • 做獨立小遊戲 Canvas2D
  • 做網頁互動角色 DOM

這項目我最大的感受

其實不同技術棧背後,
代表的是完全不同的渲染思維。

  • WebGL 想的是:GPU 怎麼畫
  • Canvas2D 想的是: 我這一幀怎麼繪製
  • DOM 想的是:瀏覽器怎麼佈局和合成

它們甚至不是同一種世界觀。


最後

這個倉庫本質上其實不是「做動畫」。
而是在研究:

瀏覽器到底是怎麼把東西畫出來的。

以上內容建議配合程式碼食用:https://github.com/iAJue/CanvasGame

上回做這種對比的時候已經是上回了: 《如何優雅的提交一個表單》
图 91