lottie动画浅入浅出《一》

1,022 阅读7分钟

lottie介绍

Lottie 是一个应用十分广泛动画库,适用于Android、iOS、Web、ReactNative、Windows的库,它解析了用Bodymovin导出为json的Adobe After Effects动画,并在移动和网络上进行了原生渲染。其和 GSAP 这类专注动画曲线、插值等js动画库不同,它本质上是一套跨平台的平面动画解决方案。其提供了一套完整得从AE到各个终端的工具流,通过AE的插件将设计师做的动画导出成一套定义好的json文件,之后再通过渲染器进行渲染,它提供了“SVG”、“Canvas”和“HTML”三种渲染模式,最常用的是第一种和第二种。

         Lottie 支持渲染播放 AE 动画。通过 AE 插件 bodymovie 导出 json 文件作为动画数据。Airbnb的开发者将其作为一个开源平台,不仅是为了免费发布,也是为了打造一个社区。他们创建了一个github地址(github.com/lottiefiles…

lottie原理

  • Lottie通过读取json文件信息实现动画效果。
  • json信息包括json整体结构、图片资源、图层信息等,这些属性阐述了动画该做什么、该怎么做。
  • json文件解析:

Lottie动画Json结构分为4层:

  1. 结构层:可以读取到动画画布的宽高,帧数,背景色,时间,起始关键帧,结束帧等信息。
  2. asset:图片资源信息集合,这里放置的是 制作动画时引用的图片资源。
  3. layers:图层集合,这里可以获取到多少图层,每个图层的开始帧 结束帧等。
  4. shapes:元素集合,可以获取到每个图层都包含多个动画元素。

最外层json

{
    "v": "5.1.13", // bodymovin 版本
    "fr": 30, // 帧率
    "ip": 0, // 起始关键帧
    "op": 20, // 结束关键帧
    "w": 150, // 视图宽
    "h": 130, // 视图高
    "nm": "鹅头收起动画", // 名称
    "ddd": 0, // 3d
    "assets": [], // 资源集合 
    "layers": [], // 图层集合
    "masker": [] // 蒙层集合
}

由于assets、layers、masker里面的数据可能很大,所以上面用空数组代替。其中layers是一个图层集合,它里面数据一般很大,里面包含了当前动画的所有图层数据,assets是一个资源集合,它里面包含了当前动画使用的资源图层数据。masks则表示蒙层集合,里面包含了所有的蒙层数据。

图层元素 layer

动画是由一个一个的图层组合起来,并在图层上进行偏移、缩放等操作来实现动画的。图层的解析是lottie的主要功能模块.

{
    "ddd": 0, // 是否为3d
    "ind": 1, // layer的ID,唯一
    "ty": 0, // 图层类型。
    "nm": "鹅头收起", // 图层名称
    "refId": "comp_0", // 引用的资源,图片/预合成层
    "sr": 1,
    "ks": {}, // 变换。对应AE中的变换设置,下面有详细介绍
    layer: [], // 该图层包含的子图层
    shaps: [], // 形状图层
    "ao": 0,
    "w": 1334,
    "h": 750,
    "ip": 0, // 该图层开始关键帧
    "op": 60, // 该图层结束关键帧
    "st": 0, // 该图层
    "bm": 0
}

其中说明一下nm属性,该属性是在AE中对该图层的命名,通过在SVG中修改该命名,可以设置对应的svg的class和id。如果命名为'#svgId',生成的对应的svg元素的id则为'svgId';如果命名为'.svg-class',则生成的对应的svg元素的class为'svg-class'。

ty表示类型,例如:

  • 2: image,图片
  • 0: comp,合成图层
  • 1: solid;
  • 3: null;
  • 4: shape,形状图层
  • 5: text,文字

ks变换

ks对应AE中图层的变换属性,可以通过设置锚点、位置、旋转、缩放、透明度等来控制图层,并设置这些属性的变换曲线,来实现动画。下面是一个ks属性值:

"ks": { // 变换。对应AE中的变换设置
    "o": { // 透明度
        "a": 0,
        "k": 100,
        "ix": 11
    },
    "r": { // 旋转
        "a": 0,
        "k": 0,
        "ix": 10
    },
    "p": { // 位置
        "a": 0,
        "k": [-167, 358.125, 0],
        "ix": 2
    },
    "a": { // 锚点
        "a": 0,
        "k": [667, 375, 0],
        "ix": 1
    },
    "s": { // 缩放
        "a": 0,
        "k": [100, 100, 100],
        "ix": 6
    }
}

shape层

shape参数的值,对应AE中图层的内容中的形状设置的内容,其主要用于绘制图形。下面一个shape的json为例:

"shapes": [{
  "ty": "gr", // 类型。混合图层
  "it": [{ // 各图层json
      "ind": 0,
      "ty": "sh", // 类型,sh表示图形路径
      "ix": 1,
      "ks": {
          "a": 0,
          "k": {
              "i": [ // 内切线点集合
                  [0, 0],
                  [0, 0]
              ],
              "o": [ // 外切线点集合
                  [0, 0],
                  [0, 0]
              ],
              "v": [ // 顶点坐标集合
                  [182, -321.75],
                  [206.25, -321.75]
              ], 
              "c": false // 贝塞尔路径闭合
          },
          "ix": 2
      },
      "nm": "路径 1",
      "mn": "ADBE Vector Shape - Group",
      "hd": false
  },{
    "ty": "st", // 类型。图形描边
    "c": { // 线的颜色
        "a": 0,
        "k": [0, 0, 0, 1],
        "ix": 3
    },
    "o": { // 线的不透明度
        "a": 0,
        "k": 100,
        "ix": 4
    },
    "w": { // 线的宽度
        "a": 0,
        "k": 3,
        "ix": 5
    },
    "lc": 2, // 线段的头尾样式
    "lj": 1, // 线段的连接样式
    "ml": 4, // 尖角限制
    "nm": "描边 1",
    "mn": "ADBE Vector Graphic - Stroke",
    "hd": false
  }]
}]

不同的shape类型,参数也不同。shape对应的是AE中的图层的内容的设置。shape中的ty字段表示shape的类型,ty有以下几种:

  • gr: 图形合并
  • st: 图形描边
  • fl: 图形填充
  • tr: 图形变换
  • sh: 图形路径
  • el: 椭圆路径
  • rc: 矩形路径
  • tm: 剪裁路径

  1. 动画加载准备,在使用Lottie加载动画前需先通过插件 bodymovin 将AE生成的动画文件转换为通用的 json 格式描述文件。开发者也可以从互联网获取合适的动画资源直接应用。

    获取链接:lottiefiles.com/

  2. 获取json文件中的动画数据。

  3. 解析json文件中的动画数据。

  4. 创建动画实例,设置动画信息。

  5. 初始化布局宽高,设置绘制样式等信息。

  6. 启动动画,触发逐帧绘制。

  7. 更新动画进度。

  8. 返回动画实例,通过loadAnimation()接口返回动画实例AnimationItem。

  9. 控制动画,Lottie提供了一整套简洁易用API,如停止stop()、暂停pause()、播放play()、播放流转togglePause()、方向setDirection()、速度setSpeed()等。 

 基本使用

安装 lottie-web

npm install lottie-web --savenpm 

初始化

import lottie from 'lottie-web'

const animation = lottie.loadAnimation({
   container: document.getElementById('box'),
   renderer: 'svg',// 渲染方式:svg、canvas
   loop: true,  // 循环播放,默认:false
   autoplay: true, //自动播放 ,默认:true
   path: ' '  // json 路径
 })

常用方法

animation.play(); // 播放,从当前帧开始播放

animation.stop(); // 停止,并回到第0帧

animation.pause(); // 暂停,并保持当前帧

// 跳到某个时刻/帧并停止isFrame(默认false)指示value表示帧还是时间(毫秒animation.goToAndStop(value, isFrame); 

animation.goToAndPlay(value, isFrame); // 跳到某个时刻/帧并进行播放

animation.goToAndStop(30, true); // 跳转到第30帧并停止

animation.goToAndPlay(300); // 跳转到第300毫秒并播放
// arr可以包含两个数字或者两个数字组成的数组,forceFlag表示是否立即强制播放该片段animation.playSegments(arr, forceFlag); 

animation.playSegments([10,20], false); // 播放完之前的片段,播放10-20帧

animation.playSegments([[0,5],[10,18]], true); // 直接播放0-5帧和10-18帧

animation.setSpeed(speed); // 设置播放速度,speed为1表示正常速度

animation.setDirection(direction); // 设置播放方向,1表示正向播放,-1表示反向播放

animation.destroy(); // 删除该动画,移除相应的元素标签等。在unmount的时候,需要调用该方法

事件监听

animation.addEventListener('data_ready', () => {
  console.log('animation data has loaded');
});

* complete: 播放完成(循环播放下不会触发)
* loopComplete: 当前循环下播放(循环播放/非循环播放)结束时触发
* enterFrame: 每进入一帧就会触发,播放时每一帧都会触发一次,stop方法也会触发
* segmentStart: 播放指定片段时触发,
playSegments、resetSegments等方法刚开始播放指定片段时会发出,如果playSegments播放多个片段,
多个片段最开始都会触发。
* data_ready: 动画json文件加载完毕触发
* DOMLoaded: 动画相关的dom已经被添加到html后触发
* destroy: 将在动画删除时触发

推荐工具

LottieFiles(lottiefiles.com/)是一个独立于Airb…, 而这些只需要你有一个免费的账号。LottieFiles同时也是一个AE的插件跟Bodymoving类似,只是功能更加丰富,允许我们「预览」动画,「上传到」LottieFiles平台,保存到我们的电脑上,等等。

洛丽塔(design.alipay.com/lolita)阿里初版…