都2022年了,一個還不知道Lottie動畫的前端已經OUT啦!

語言: CN / TW / HK

持續創作,加速成長!這是我參與「掘金日新計劃 · 6 月更文挑戰」的第1天,點選檢視活動詳情

這是一篇可以釋放前端同學壓力,解放人力,提高生產力的文章。

一、為什麼會有Lottie動畫呢?

在前端程式設計師根據UI視覺稿實現頁面效果時一直存在這樣的一種“矛盾” - 動畫效果更完美與工期成本的矛盾。一般來說,頁面中包含的動畫效果越複雜,前端程式設計師在實現時需要的工期成本越大,尤其是在官網、大促活動、活動拉新等包含巨多動畫效果的場景中,動畫實現需要的時間佔據了大部分工期時間,而工期往往是非常緊湊的。同時後期還經常伴隨著與UI設計師的反覆“拉扯” - 動畫方向要改變下,運動的路徑曲線要再調整下,這個圓角值不太圓,這個圖片辛苦再替換下。諸如此類,都是讓程式設計師腦袋變禿的罪魁禍首之一!

頭禿了

在反覆的拉扯“折磨”中,有一批程式設計師就在不停的思索,將動畫的設計實現與使用進行物理分割,讓專業的人做更專業的事兒!

  1. 產出某種物料:讓對色彩、互動更專業的UI同學完成動畫的設計、實現、優化,產出一種可供識別的物料;
  2. 以某種形式直接識別、使用物料:前端研發通過某種形式直接識別該物料,呼叫後頁面直接渲染動畫,無須再配置路徑動畫、描邊動畫等;

基於這樣的思考與探索,Lottie動畫應運而生!

二、Lottie介紹

Lottie是一款由airbnb開源的跨平臺動畫渲染庫,支援Android, iOS, Web, Windows平臺。是專門用於解析從AE(Adobe After Effects)中通過Bodymovin外掛匯出的JSON檔案,直接渲染動畫。

Lottie官網的傳送門在此點我你將見證神奇

本文的重點在於如何使用匯出的JSON檔案,在AE中如何開發動畫以及外掛Bodymovin的使用歡迎查閱其他相關資料~

一圖勝千言 ~ 程式碼片段

該示例程式碼如下:

```html

Lottie

```

開發人員進行簡單的配置,引入Lottie,載入相應的JSON檔案,動畫就實現了!簡不簡單,神不神奇!

專業的人做專業的事兒,後期即使UI設計MM又多動畫做出了調整,做為開發的你唯一需要做的就是將檔案替換一下即可!是不是又可以挽救幾根頭髮了~

Lottie Files是一個專門針對Lottie動畫設計、分享的網站。你可以在這個網站上上傳自己製作的lottie動畫,也可以瀏覽其他設計師上傳的lottie動畫,也可以快速體驗,方便而有趣。

三、Lottie常見屬性和方法

loadAnimation引數配置

| 屬性名 | 描述 | | --- | --- | | container | 渲染動畫所需容器 | | renderer | 動畫渲染型別,svg/canvas/html | | loop | 是否迴圈播放,布林值 | | autoplay | 是否自動播放,布林值 | | path | 一個指定的JSON檔案路徑 | | animationData | JSON動畫資料,與path屬性不共存 |

考慮頁面效能更優,建議使用svg渲染方式,通過path載入遠端JSON檔案,使用animationData會讓json檔案打包到JS中,

loadAnimation方法返回的物件

| 屬性名 | 型別 | 描述 | | --- | --- | --- | | play | () => void | 播放動畫 | | pause | () => void | 暫停動畫 | | stop | () => void | 停止動畫 | | play | () => void | 播放動畫 | | setSpeed | (number) => void | 設定播放速度 | | destroy | () => void | 銷燬動畫 |

四、封裝Lottie - React Hooks版

為了在專案中能夠快速複用,將Lottie動畫渲染簡易封裝成react元件Lottie

安裝依賴

```shell

lottie-web是針對web渲染的庫

yarn add lottie-web ```

Lottie元件封裝:

```tsx import React, { useRef, useEffect, useMemo, forwardRef, useImperativeHandle, Ref } from 'react'; import lottie, { AnimationItem } from 'lottie-web';

// 渲染型別 type rendererType = 'svg' | 'canvas' | 'html';

// 常用屬性 interface IProps { // 是否迴圈播放 loop?: boolean; // 渲染動畫的型別 renderer?: rendererType; // 是否自動播放 autoplay?: boolean; // 動畫渲染資料,與path互斥 animationData?: any; // JSON檔案路徑,與animationData互斥 path?: string; }

export default forwardRef((props: IProps, ref: Ref) => { // 設定props的預設值 const { loop = true, renderer = 'svg', path = '', animationData, autoplay = true } = props;

// 設定動畫渲染的容器 const containerEle = useRef(null); // 對外暴露的ref物件 const lottieAnimation = useRef(null);

// 指定想父級呼叫元件暴露的ref物件,方便元素控制當前動畫的播放與暫停 useImperativeHandle(ref, () => lottieAnimation.current);

// 快取動畫的相關配置 const animationOptions = useMemo(() => { const options: IProps = { loop, renderer, autoplay };

// 優先取animationData
if (animationData) {
  options.animationData = animationData;
} else {
  options.path = path;
}

return options;

}, [loop, renderer, path, animationData]);

useEffect(() => { if (!containerEle.current) { return; }

// 渲染動畫
const lottieAnimationItem: AnimationItem = lottie.loadAnimation({
  container: containerEle.current,
  ...animationOptions
});

// 將渲染後的動畫示例物件賦值給lottieAnimation.current,對外暴露
lottieAnimation.current = lottieAnimationItem;

// 一定要注意這裡的物件銷燬,避免記憶體洩露,以及重複渲染動畫
return () => {
  if (!containerEle.current) {
    return;
  }
  // 重置為null
  lottieAnimation.current = null;
  // 銷燬動畫物件
  lottieAnimationItem.destroy();
};

}, [containerEle.current, animationOptions]);

// 因為lottie動畫是無線寬高的,所以這裡直接設定渲染的容器寬度、高度為父級元素100%即可 return

; }); ```

五、Lottie元件的引入與呼叫

  1. 指定path的方式

```tsx import "./styles.css"; import Lottie from "./lottie"; import animationData from "./animation.json";

export default function App() { return (

{/ 指定路徑 /}
{/ 指定animationData /}
); } ```

codesandbox地址:http://codesandbox.io/s/funny-resonance-dlpitg

效果圖:

CPT2205252132-1131x409.gif

結語

以上就是胡哥今天給大家分享的內容,喜歡的小夥伴記得點贊收藏呀,關注胡哥有話說,學習前端不迷路,歡迎多多留言交流...