如果在Flutter Web项目中使用lottie动画

Posted BennuCTech

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如果在Flutter Web项目中使用lottie动画相关的知识,希望对你有一定的参考价值。

前言

lottie虽然支持很多平台,但是目前还没有flutter版,那么想要在flutter项目中使用lottie就需要通过调用原生sdk的方式。所以在flutter web项目中我们需要用lottie的js版本,那么具体如何使用呢?本文将会将lottie封装成一个组件,方便大家使用。

引入js

首先在index.html中添加lottie的js文件,如下:

<script type="text/javascript" src="js/lottie.js" acync></script>

ScriptElement

用ScriptElement封装lottie,如下:

var script = """
var lottieAnim = document.getElementById("lottie_anim");  //渲染模式如果是html,则不能直接这么获取;如果是canvas则可以
if(!lottieAnim)
  var roots = document.getElementsByTagName("flt-platform-view");
  for(var i = 0; i < roots.length; i++)
    var tmp = roots[i].shadowRoot.getElementById("lottie_anim");
    if(tmp)
      lottieAnim = tmp;
    
  


var lottieObj = lottie.loadAnimation(
container:lottieAnim,
renderer: 'svg',
loop:$widget.isLoop,
autoplay:$widget.isAutoPlay,
path:"assets/$widget.path"
);
""";
ScriptElement scriptElement = new ScriptElement();
scriptElement.innerHtml = script;

首先我们需要获取到lottie_anim,这里需要注意flutter web的渲染模式(参考:Flutter Web:Shadow Root问题),如果是canvas模式则直接getElementById就可以获取;但是如果是html模式,因为Shadow Root问题无法直接获取到,所以在代码中如果通过getElementById获取是空的,就特殊处理一下。

然后通过loadAnimation来加载动画,这里需要三个参数loop、autoplay和path,因为打算封装成一个组件,所以这些参数我定义为widget的属性,从外面传进来。

交互

我们还需要添加一些交互,比如播放、暂停、停止等,如下:

var lottiePlay = function()
  lottieObj.play();


var lottiePause = function()
    lottieObj.pause();       


var lottieStop = function() 
    lottieObj.stop();

这样在flutter中,就可以通过js.context.callMethod来执行对应的方法,如下

void lottiePlay() 
  js.context.callMethod("lottiePlay");


void lottieStop() 
  js.context.callMethod("lottieStop");


void lottiePause() 
  js.context.callMethod("lottiePause");

还需要添加一个监听,来监听动画是否执行完成,以便执行后续操作,如下

// 动画播放完成触发
lottieObj.addEventListener('complete', lottieLoaded);

在flutter中注册这个监听,如下

js.context["lottieLoaded"] = lottieLoaded;
...
// 动画播放完成触发
void lottieLoaded(String args) 
    widget._animationListener?.call();

这里通过由外部来传入监听,以便各自进行处理。

HtmlElementView

然后将ScriptElement封装到HtmlElementView中以便使用,如下:

@override
Widget build(BuildContext context) 
  js.context["lottieLoaded"] = lottieLoaded;

  DivElement divElement = DivElement();
  divElement.id = "lottie_anim";

  StyleElement styleElement = StyleElement();
  styleElement.type = "text/css";
  styleElement.innerHtml = """
        html,
        body 
        
        """;
  divElement.append(styleElement);

  var script = """
  ...
  """;
  ScriptElement scriptElement = new ScriptElement();
  scriptElement.innerHtml = script;
  divElement.append(scriptElement);

  String _divId = "lottieanim" + DateTime.now().toIso8601String();
  ui.platformViewRegistry.registerViewFactory(
    _divId,
    (int viewId) => divElement,
  );
  Widget _iframeWidget = HtmlElementView(
    key: UniqueKey(),
    viewType: _divId,
  );

  return SizedBox(child: _iframeWidget, width: widget.width, height: widget.height,);

注意这里viewType没有使用固定值,因为如果同时有多个动画的话,使用固定值会导致问题。

最后用一个SizedBox封装一下,设置一些动画的长宽即可,这样可以保证动画完整的显示,这个长宽同样由外部传入。

使用

封装成LottieWidget组件后,使用起来非常简单,如下:

LottieWidget(path,width, height, true, false, ()
  //动画结束处理
);

参数分别是:动画路径、宽度、长度、是否自动播放,是否循环播放,动画监听。

关注公众号:BennuCTech,获取更多干货!

以上是关于如果在Flutter Web项目中使用lottie动画的主要内容,如果未能解决你的问题,请参考以下文章

flutter web:lottie jssdk报错处理

flutter 启动屏幕使用 Lottie 动画

Flutter Web:Shadow Root问题

Flutter 专题50 图解动画小插曲之 Lottie 动画 #yyds干货盘点#

Flutter listview下拉刷新,上拉加载更多封装

Lottie 动画在项目中的使用总结