精靈圖在 Lottie Web 動畫中的應用
概述
Lottie
是一套跨平臺的平面動畫解決方案;設計師使用AE
設計動畫,然後通過外掛將動畫匯出成定義好的json
檔案;之後開發人員只需要依賴這個 json 檔案和對應平臺的Lottie
動畫庫就可以很方便的在相應平臺中實現動畫了。
普通示例
普通示例線上預覽連結為 newbieyoung.github.io/lottie-web-…;
原始碼在 lottie-web-sprite 專案中。
在 Web 平臺則需要使用 Lottie Web;
可以去 cdnjs.cloudflare.com/ajax/libs/b… 下載壓縮後的原始碼,或者去 cdnjs.cloudflare.com/ajax/libs/b…
設計師使用 AE 匯出如下資源:
格式化其 json 檔案內容可以看到:
其中需要注意w
、h
、assets
;
w
表示動畫畫布寬度;h
表示動畫畫布高度;assets
表示images
目錄中的圖片資源資訊;
知道動畫畫布寬度和高度之後,我們就可以設定頁面中的動畫容器寬度和高度了;
div{
width:280px;
height:280px;
}
複製程式碼
<div id="animation"></div>
複製程式碼
動畫容器為DIV
元素,其ID
屬性為animation
,其寬度和高度均為280
;
之後需要引入框架原始碼,這裡使用未壓縮版本,方便除錯;
<script src="./lib/lottie.js"></script>
複製程式碼
引入程式碼之後只需要呼叫lottie.loadAnimation()
就可以實現動畫了;
var animation = document.querySelector('#animation');
lottie.loadAnimation({
container: animation,
renderer: 'canvas',
loop: true,
autoplay: true,
path: './animation/data.json'
});
複製程式碼
container
表示動畫容器;renderer
表示渲染器,目前支援的渲染器有html
、svg
、canvas
,較常用的是svg
和canvas
;loop
表示動畫迴圈播放;autoplay
表示動畫自動播放;path
則表示json
檔案路徑。
到此整個動畫實現就完成了。
初一看起來沒有任何問題,但是當我們開啟瀏覽器除錯工具,檢視資源載入情況時就會發現有點問題:
設計師通過 AE 匯出的資源裡邊存在圖片資源,而這些圖片資源沒有經過任何處理是單獨載入的,這會導致載入的資源數量過多,特別是當一個頁面存在多個獨立動畫時。
這個問題可以通過把圖片資源整合到 json 檔案中的方式解決,最終設計師匯出的資源就只有一個 json 檔案,不過這種方式需要設計師在匯出資源時進行處理,而且需要先把圖片轉換成向量圖。
對於我來說這種方式會顯得有點麻煩,首先我並不清楚怎麼把圖片資源轉換成向量圖然後整合 json 檔案,甚至連 AE 都沒安裝過;對於一個本身並不清楚而且也沒有實際操作經驗的問題,自然也就很難跟設計師講清楚了。
那有沒有其它我擅長的方式呢?
精靈圖示例
精靈圖示例線上預覽連結為 newbieyoung.github.io/lottie-web-…;
原始碼在 lottie-web-sprite 專案中。
開啟瀏覽器除錯工具,可以清楚的看到圖片資源都被整合在一張精靈圖中了。
原始碼解析及思路
怎麼實現呢?在沒有思路的時候看看原始碼好了。
從loadAnimation
方法開始,到animItem.setParams(params)
在設定並解析引數,最後在assetLoader.load
方法中載入 json 檔案,載入完成之後執行this.configAnimation.bind(this)
配置動畫回撥函式;
其中this.animationData
即是解析 json 檔案內容得到動畫資料,其assets
屬性為圖片資訊陣列;忽略其它流程,重點關注this.preloadImages()
,在這個方法中會通過assets
載入對應圖片資源;
loadAssets
方法會根據圖片資訊陣列傳送非同步請求載入圖片資源,然後生成img
元素,整合到ImagePreloader
物件的images
屬性中。
到這裡雖然並沒有弄清楚Lottie
是怎麼根據json
檔案實現動畫的,但是可以清楚看到它是怎麼解析json
檔案然後載入相應圖片素材的;
根據上述流程怎麼在Lottie
中應用精靈圖的思路也就漸漸清晰了,我們只要保證通過精靈圖得到和上述流程中一樣的images
陣列資料就可以了。
生成精靈圖
可以用 lia 生成精靈圖;
用法很簡單:
- 使用
npm
全域性安裝lia
;
npm i -g lia
複製程式碼
- 建立精靈圖配置檔案
sprite_conf.js
;
使用
lia init
命令可以自動生成配置檔案,只不過因為需要使用自定義模版,所以這裡手動建立。
src
表示圖片素材路徑匹配規則;image
表示生成的精靈圖的路徑;style
表示生成的圖片素材和精靈圖的位置關係資料檔案的路徑;tmpl
表示圖片素材和精靈圖的位置關係資料檔案模版。
- 建立圖片素材和精靈圖的位置關係資料模版檔案
template.ejs
;
- 執行
lia
命令。
lia
複製程式碼
就得到了精靈圖以及位置關係資料檔案。
最後需要把位置關係資料檔案中的絕對路徑改為相對路徑。
更改 json 檔案
更改 json 檔案很簡單隻需要先讀取內容,然後新增自定義欄位,最後儲存即可。
更改原始碼
資料都準備完成了,接下來需要對Lottie
的原始碼進行相容處理。
相容處理之後的完整原始碼在github.com/newbieYoung…。
首先在configAnimation
方法中,如果解析的 json 資料存在_sprite
屬性,則使用preloadSprite
方法從精靈圖中獲取圖片素材,否則按以前的流程使用preloadImages
方法從assets
陣列中獲取圖片素材;不管是哪種獲取圖片素材的方式,後續流程都保持不變。
preloadSprite
和preloadImages
兩個方法的邏輯基本類似,除了前者使用自定義方法loadAssetsFromSprite
,後者使用原生方法loadAssets
。
在loadAssetsFromSprite
方法中,先根據精靈圖路徑非同步請求精靈圖,然後根據位置關係從精靈圖中動態獲取相關圖片素材,並設定到images
屬性中即可。
至此就可以在Lottie
中應用精靈圖了。