最近我做了個挺有意思的小實驗。
我把一個二次元角色的小動畫效果,分別用:
- 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
上回做這種對比的時候已經是上回了: 《如何優雅的提交一個表單》
