精灵图在 Lottie Web 动画中的应用

© Young 2018-12-13 21:43
Welcome to My GitHub

概述

Lottie是一套跨平台的平面动画解决方案;设计师使用AE设计动画,然后通过插件将动画导出成定义好的json文件;之后开发人员只需要依赖这个 json 文件和对应平台的Lottie动画库就可以很方便的在相应平台中实现动画了。

普通示例

普通示例在线预览链接为 https://newbieyoung.github.io/lottie-web-sprite/normal.html

源代码在 lottie-web-sprite 项目中。

在 Web 平台则需要使用 Lottie Web

可以去 https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.4.2/lottie.min.js 下载压缩后的源代码,或者去 https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.4.2/lottie.js 下载未压缩源代码;

设计师使用 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 都没安装过;对于一个本身并不清楚而且也没有实际操作经验的问题,自然也就很难跟设计师讲清楚了。

那有没有其它我擅长的方式呢?

精灵图示例

精灵图示例在线预览链接为 https://newbieyoung.github.io/lottie-web-sprite/sprite.html

源代码在 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的源代码进行兼容处理。

兼容处理之后的完整源代码在https://github.com/newbieYoung/lottie-web-sprite/blob/master/lib/lottie-sprite.js

首先在configAnimation方法中,如果解析的 json 数据存在_sprite属性,则使用preloadSprite方法从精灵图中获取图片素材,否则按以前的流程使用preloadImages方法从assets数组中获取图片素材;不管是哪种获取图片素材的方式,后续流程都保持不变。

preloadSpritepreloadImages两个方法的逻辑基本类似,除了前者使用自定义方法loadAssetsFromSprite,后者使用原生方法loadAssets

loadAssetsFromSprite方法中,先根据精灵图路径异步请求精灵图,然后根据位置关系从精灵图中动态获取相关图片素材,并设置到images属性中即可。

至此就可以在Lottie中应用精灵图了。

发表评论

电子邮件地址不会被公开。 必填项已用*标注