如果在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动画的主要内容,如果未能解决你的问题,请参考以下文章