前端動畫效果實現的簡單比較

chemzqm發表於2019-01-09

  合適的動畫不僅更能吸引人們的眼球,也能讓你的應用體驗更為流暢,而將動畫的效果做到極致,才能讓使用者感到使用你的應用是一種享受,而不是覺得生硬和枯燥。本文旨在探討各種前端動畫效果實現方式的異同,具體應用中如何實現,以及實現的效果還得根據自身的情況進行考量。

 Javscript 動畫

  因為沒有其它可用的實現方式,最初的前端動畫都是JS來實現,實現上就是通過一個定時器setInterval 每隔一定時間來改變元素的樣式,動畫結束時clearInterval即可。早期的類庫包括 jquery、prototype、mootools 等等都是這種方式。

  儘管這種方式動畫的可控性很強,但是問題也很明顯:

  • 效能不佳,因為需要不斷獲取和修改Dom的佈局,所以導致了大量頁面重排(repaint)
  • 缺乏標準,不同的庫使用了不同的API,導致即使是簡單的動畫也有各不相同的實現方式,調整起來比較耗時
  • 頻寬消耗,相對豐富的動畫庫程式碼量都很大,結果就是增加了http請求的大小,降低了頁面的載入時間

 css3 動畫

  css3 加了兩種動畫的實現方式,一種是 transition, 一種是 animation。

  transition 包含4種屬性:transition-delay transition-duration transition-property transition-timing-function,對應動畫的4種屬性: 延遲、持續時間、對應css屬性和緩動函式,

  transform 包含7種屬性:animation-name animation-duration animation-timing-function animation-delay animation-direction animation-iteration-count animation-fill-mode animation-play-state,它們可以定義動畫名稱,持續時間,緩動函式,動畫延遲,動畫方向,重複次數,填充模式。

  總的來書,css 動畫相比與JS更輕量,效能更好,更易於實現,同時也不必擔心缺乏標準和增加頻寬消耗的問題。animation 相比 transtion 使用起來更為複雜,但也提供了更多的控制,其中最重要的就是 frame 的支援,不過通過一些簡單的JS庫,例如 TJ 的 move.js, 我們也能在JS中通過 transition 來實現更復雜的控制。

 html5 動畫

  html5 定義了三種繪圖的方式,canvas svg webgl,其中svg做為一種可縮放向量圖形的實現是基於xml標籤定義的,它有專門的 animate 標籤來定義動畫。而為 canvas 或者 webgl 實現動畫則需要通過 requestAnimationFrame (簡稱 raf) 來定期重新整理畫布。 儘管說 raf 的方式會讓程式碼變得複雜,但是因為不需要那麼多的文件物件(通常瀏覽器只需要管理一個畫布),它的效能也好很多,尤其是在記憶體吃緊的移動端上面。

  通過新的 raf 介面以及一些改進手段我們也可以用JS來實現高效能的動畫。主要手段如下:

  1. 減少 Dom 樣式屬性查詢,Dom 樣式屬性的查詢會導致頁面重排,從而消耗效能,通過將屬性儲存在JS變數中就可以避免在動畫時去查詢,從而減少卡頓。

  2. 使用效能更好的 css transform 替代改變絕對定位元素的定位屬性

  3. 在移動裝置上使用 3d 硬體加速,最簡單辦法就是新增 -webkit-transform: translateZ(0),原因是移動端的顯示卡有很強的圖形渲染能力,而每個應用的 webview 記憶體卻是極其有限的。

  使用JS的動畫可控性更好,比如說通過事件捕捉可以很容易的設定不同引數。這方面做的最全面的有 Velocity.js,它可做為jquery 外掛使用,對於初學者很友好。

相關文章