1. 程式人生 > >精靈圖在 Lottie Web 動畫中的應用

精靈圖在 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 檔案內容可以看到:

其中需要注意whassets

  • 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表示渲染器,目前支援的渲染器有htmlsvgcanvas,較常用的是svgcanvas
  • 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 生成精靈圖;

用法很簡單:

  1. 使用npm全域性安裝lia
npm i -g lia
複製程式碼
  1. 建立精靈圖配置檔案sprite_conf.js

使用lia init命令可以自動生成配置檔案,只不過因為需要使用自定義模版,所以這裡手動建立。

  • src表示圖片素材路徑匹配規則;
  • image表示生成的精靈圖的路徑;
  • style表示生成的圖片素材和精靈圖的位置關係資料檔案的路徑;
  • tmpl表示圖片素材和精靈圖的位置關係資料檔案模版。
  1. 建立圖片素材和精靈圖的位置關係資料模版檔案template.ejs
  1. 執行lia命令。
lia
複製程式碼

就得到了精靈圖以及位置關係資料檔案。

最後需要把位置關係資料檔案中的絕對路徑改為相對路徑。

更改 json 檔案

更改 json 檔案很簡單隻需要先讀取內容,然後新增自定義欄位,最後儲存即可。

更改原始碼

資料都準備完成了,接下來需要對Lottie的原始碼進行相容處理。

相容處理之後的完整原始碼在github.com/newbieYoung…

首先在configAnimation方法中,如果解析的 json 資料存在_sprite屬性,則使用preloadSprite方法從精靈圖中獲取圖片素材,否則按以前的流程使用preloadImages方法從assets陣列中獲取圖片素材;不管是哪種獲取圖片素材的方式,後續流程都保持不變。

preloadSpritepreloadImages兩個方法的邏輯基本類似,除了前者使用自定義方法loadAssetsFromSprite,後者使用原生方法loadAssets

loadAssetsFromSprite方法中,先根據精靈圖路徑非同步請求精靈圖,然後根據位置關係從精靈圖中動態獲取相關圖片素材,並設定到images屬性中即可。

至此就可以在Lottie中應用精靈圖了。