Flutter 134: 圖解動(dòng)畫小插曲之 SVGA 動(dòng)畫

????小菜之前嘗試了 FlareLottie 動(dòng)畫,實(shí)現(xiàn)效果都很高效刁标;今天小菜嘗試另一種思路 SVGA 動(dòng)畫感猛;SVGA 是一種同時(shí)兼容 iOS / Android / Flutter / Web 多個(gè)平臺(tái)的動(dòng)畫格式;

SVGA

基本簡介

????小菜首先贊美一下 SVGA 官網(wǎng)照弥,非常簡潔而且主要信息都容易查到言津,同時(shí)看著非常舒服攻人;設(shè)計(jì)師通過 AE 等工具設(shè)計(jì)生成好 SVGA 動(dòng)畫后,可直接交付給開發(fā)同學(xué)通過 SVGAPlayer 直接調(diào)用即可悬槽,集成和應(yīng)用都很簡單怀吻;

????SVGA 提供了在線動(dòng)畫素材預(yù)覽以及素材元素拆分,還可以將 SVGA 動(dòng)畫轉(zhuǎn)化為 SVG 矢量圖元素初婆,非常靈活方便蓬坡;

案例嘗試

????SVGA 提供了多種方式完整的集成方案,小菜簡單嘗試一下 Flutter 版本應(yīng)用烟逊;

1. 集成 svgaplayer_flutter

????與所有插件使用相同渣窜,小菜引入對應(yīng)版本的 svgaplayer_flutter铺根;目前 svgaplayer_flutter 已支持 Flutter 2.0 空安全宪躯;

svgaplayer_flutter: ^2.1.2

2. 應(yīng)用播放 SVGA

2.1 SVGASimpleImage 加載動(dòng)畫

????svgaplayer_flutter 支持播放本地動(dòng)畫和網(wǎng)絡(luò)線上動(dòng)畫,與 Image 加載本地和網(wǎng)絡(luò)圖片類似位迂;SVGA 提供了封裝好 SVGAAnimationController 控制器的 SVGASimpleImage访雪;根據(jù)文件類型详瑞,通過不同參數(shù)進(jìn)行展示,默認(rèn)動(dòng)畫效果為重復(fù)播放臣缀;

class SVGASimpleImage extends StatefulWidget {
  final String resUrl;
  final String assetsName;
  final File file;

  SVGASimpleImage({Key key, this.resUrl, this.assetsName, this.file}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _SVGASimpleImageState();
}

????簡單分析源碼可得坝橡,SVGASimpleImage 根據(jù)傳遞的不同動(dòng)畫路徑進(jìn)行不同方式的展示,通過 SVGAParser.shared 加載和解碼不同類型的網(wǎng)絡(luò)資源精置、本地資源以及 File 資源等计寇;

class _SVGAPageState extends State<SVGAPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('SVGA Page')),
        body: Column(children: [
          _itemSVGA01(false, 'images/posche.svga'),
          _itemSVGA01(true, 'https://github.com/yyued/SVGA-Samples/blob/master/angel.svga?raw=true')
        ]));
  }

  _itemSVGA01(isUrl, svgaUrl) {
    return Expanded( flex: 1,
        child: SVGASimpleImage(assetsName: isUrl ? null : svgaUrl, resUrl: isUrl ? svgaUrl : null));
  }
}
2.2 SVGAImage & SVGAAnimationController

????SVGASimpleImage 是將 SVGAImageSVGAAnimationController 封裝好的動(dòng)畫播放器,若我們想自由控制動(dòng)畫的播放脂倦、暫停番宁、重播等操作的話,需要配合 SVGAAnimationController 控制器調(diào)節(jié)動(dòng)畫的播放過程赖阻;

SVGAImage(
    this._controller, {
    this.fit = BoxFit.contain,
    this.clearsAfterStop = true,
})

????簡單分析源碼可得蝶押,SVGAImage 主要是通過 SVGAAnimationController 來進(jìn)行動(dòng)畫播放;與圖片類似火欧,可以通過 BoxFit 設(shè)置動(dòng)畫的布局樣式棋电;

????SVGAAnimationController 是對 AnimationController 進(jìn)一層封裝與應(yīng)用,調(diào)用的方法和狀態(tài)回調(diào)基本是一致的苇侵;

enum AnimationStatus {
  /// 動(dòng)畫開始時(shí)結(jié)束
  dismissed,

  /// 動(dòng)畫開始
  forward,

  /// 逆向動(dòng)畫
  reverse,

  /// 動(dòng)畫完成結(jié)束
  completed,
}

this.animationController ?.addStatusListener((status) => print('---status---$status'));

????SVGAAnimationController 提供了常用的播放方法赶盔,小菜簡單嘗試幾種常用的;

  • reset 動(dòng)畫重置衅檀;
  • forward 動(dòng)畫播放招刨,小菜建議若動(dòng)畫從頭開始播放先調(diào)用 reset 使動(dòng)畫重置,防止其他操作影響動(dòng)畫起始位置哀军;
  • stop 動(dòng)畫停止沉眶,與 Lottie 動(dòng)畫不同,SVGAAnimationController 沒有提供對應(yīng)的暫停方法杉适,小菜將 stop 理解為暫停和停止谎倔,若繼續(xù)播放則調(diào)用 forward 即可;
  • reverse 動(dòng)畫反轉(zhuǎn)猿推,即反向播放動(dòng)畫片习;
  • repeat 動(dòng)畫重復(fù);
  • fling 使用臨界阻尼彈簧和初始速度驅(qū)動(dòng)動(dòng)畫蹬叭;小菜簡單理解在正向播放時(shí)藕咏,fling 會(huì)按起始速度播放完成;
@override
void initState() {
  super.initState();
  this.animationController = SVGAAnimationController(vsync: this)
    ..addListener(() {
      if (mounted) { setState(() {}); }
    });
  this._loadAnimation();
}

@override
void dispose() {
  this.animationController?.clear();
  this.animationController?.dispose();
  this.animationController = null;
  super.dispose();
}

void _loadAnimation() async {
  final videoItem = await _loadSVGA(false, 'images/posche.svga');
  if (mounted)
    setState(() {
      this.isLoading = false;
      this.animationController?.videoItem = videoItem;
      this.animationController ?.addStatusListener((status) => print('---status---$status'));
    });
}

Widget _itemBtn(str) => Expanded(
    child: Container(
        margin: EdgeInsets.all(1.0),
        child: FlatButton(
            color: Colors.lightBlueAccent,
            child: Text(str),
            onPressed: () {
              if (str == 'start') {
                animationController?.reset();
                animationController?.forward();
              } else if (str == 'reverse') {
                animationController?.reverse();
              } else if (str == 'repeat') {
                animationController?.repeat();
              } else if (str == 'resume') {
                animationController?.forward();
              } else if (str == 'stop') {
                animationController?.stop();
              } else if (str == 'fling') {
                animationController?.fling();
              }
              setState(() {});
            })));

SVAG & Lottie

????小菜查閱了一些資料秽五,簡單了解了 SVGALottie 動(dòng)畫實(shí)現(xiàn)方式的差異孽查;SVGA 是將 SVGA 矢量圖逐幀繪制,通過設(shè)置幀率坦喘,來生成一個(gè)配置文件盲再,使得每一幀都有一個(gè)配置西设,每一幀都是關(guān)鍵幀,通過幀率去刷每一幀的畫面答朋,這個(gè)思路跟 GIF 很像贷揽,但是通過配置使得動(dòng)畫過程中圖片都可以得到復(fù)用;

????而 Lottie 動(dòng)畫是逐層繪制梦碗,將所有的動(dòng)畫拆成多個(gè)層級(jí),每個(gè)層級(jí) layer 都有一個(gè)動(dòng)畫配置禽绪,播放時(shí)解析多 0 個(gè) layer 的配置,并給每個(gè) layer 做相應(yīng)的動(dòng)畫洪规;

????兩種動(dòng)畫模式都是很成熟且應(yīng)用范圍很廣的動(dòng)畫丐一,小菜因未找到完全相同的動(dòng)畫元素,未能進(jìn)行準(zhǔn)確的數(shù)據(jù)分析淹冰,但查閱資料兩者性能基本持平库车,具體選用哪種根據(jù)實(shí)際情況而定;


????SVGA 案例源碼


????小菜對 SVGA 的研究還很淺顯樱拴,有很多方法未研究到柠衍;如有錯(cuò)誤,請多多指導(dǎo)晶乔!

來源: 阿策小和尚

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末珍坊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子正罢,更是在濱河造成了極大的恐慌阵漏,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翻具,死亡現(xiàn)場離奇詭異履怯,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)裆泳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門叹洲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人工禾,你說我怎么就攤上這事运提。” “怎么了闻葵?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵民泵,是天一觀的道長。 經(jīng)常有香客問我槽畔,道長栈妆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮签钩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘坏快。我一直安慰自己铅檩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布莽鸿。 她就那樣靜靜地躺著昧旨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祥得。 梳的紋絲不亂的頭發(fā)上兔沃,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音级及,去河邊找鬼乒疏。 笑死,一個(gè)胖子當(dāng)著我的面吹牛饮焦,可吹牛的內(nèi)容都是我干的怕吴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼县踢,長吁一口氣:“原來是場噩夢啊……” “哼转绷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起硼啤,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤议经,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后谴返,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煞肾,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年嗓袱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扯旷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡索抓,死狀恐怖钧忽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逼肯,我是刑警寧澤耸黑,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站篮幢,受9級(jí)特大地震影響大刊,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜三椿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一缺菌、第九天 我趴在偏房一處隱蔽的房頂上張望葫辐。 院中可真熱鬧,春花似錦伴郁、人聲如沸耿战。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽剂陡。三九已至,卻和暖如春狐胎,著一層夾襖步出監(jiān)牢的瞬間鸭栖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工握巢, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留晕鹊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓暴浦,卻偏偏與公主長得像捏题,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子肉渴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容