[lottie](https://github.com/airbnb/lottie) Lottie is a library for Android, iOS, Web, and Windows that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile and on the web!

image image image image image

image image image image image image

需求背景

58HRG雇主品牌盛典自2016年首届开始,已成功举办三届,并在行业内形成了巨大影响力。在成功评选出行业内在口碑、员工满意度、美誉度各方面突出的企业外,58招聘也协同入围企业共同在品牌认可度提升、行业影响力等方面相互促进...目前每年都需要重做一版,而且历届品牌盛典项目的风格都是动画比较酷炫的,提高用户体验,but...开发时间有限,每次都需要和UI小姐姐讨论效果以及考察实现方案的可行性。

目前实现动画的方式:

  • css3 逐帧动画/补间动画
  • gif 太大
  • 前端实现svg动画 成本较高
  • canvas
    • RAF FLIP
  • WebGL: 3D框架 THREE.JS ThingJS(针对物联网领域)
  • 其他轮子 比如:

React动画

动画库

  • GSAP最炫酷的免费动画库之一
  • Velocity 简单易用、高性能、功能丰富的轻量级JS动画库
  • animation.css
  • popmotion 该库还具有指针跟踪,弹簧物理,3D动画等功能,并可用于创建功能型,反应型的动画。
  • 弹性动效库bounce.js
  • https://blog.csdn.net/weixin_34409703/article/details/91369180 滚动相关动画库
  • scrollOut
  • scrollMagic

针对特定特效,我们入手手写的话,想想都想死....,借助现有轮子的话,我们需要考察各种轮子实现方案的可能性,兼容性,性能,包大小等等方面,但是时间有限,我们需要一种简单高效高性能的动画解决方案--lottie-web

lottie

介绍: lottie是airbnb开源的一款可以解析使用AE制作的动画(需要用bodymovin导出为json格式)的库,支持web、ios、android和react native。在web端,lottie-web库可以解析导出的动画json文件,并将其以svg/canvas/HTML的方式将动画绘制到我们页面中。

image

可靠性:

  • 目前star数(2019-19-18)lottie-web18185 fork数1703 usedby 1766,
  • 最新三天前更新,开发中持续维护中
  • 目前腾讯系 QQ音乐 腾讯课堂等很多部门都有应用

优点:

  • 设计师实现动画 效果更好,且分工明确,设计师设计效果,FE实现
  • 快! 设计师AE稿利用Bodymovin插件导出JSON,开发人员只需要低啊用即可,大大减少工作量
  • 小!相比gif等json文件小很多,性能也会好
  • 几乎100%还原

缺点

  • lottie-web本身较大,但是web端可以通过本身的缓存机制提高加载性能,并且现在有light版本,如果只是在web端使用,建议统一渲染成统一格式(svg/canvas/html),会有单独对应的light版本

  • lottie_html.min.js
  • lottie_light_html.min.js
  • lottie_svg.min.js
  • lottie_light_svg.min.js
  • lottie_canvas.min.js
  • lottie_light_sanvas.min.js

引入方式

npm install lottie-web
import lottie from 'lottie-web'

lottie.loadAnimation({
  container: element, 
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: 'data.json' 
});
cdn外链版则是bodymovin.js https://cdnjs.com/libraries/bodymovin 挑选需要的版本
bodymovin.loadAnimation({
  container: element,  
  renderer: 'svg', //canvas/html
  loop: true,
  autoplay: true,
  path: 'data.json' 
});

useage

bodymovin插件安装使用

Lottie使用的前提是使用bodymovin插件将AE导出json

bodymovin的主要功能是将 AE 导出的动画在 Web 端执行,而Lottie的主要作用是将动画在移动端运行。

1.下载地址: https://github.com/bodymovin/bodymovin/releases

2.安装 ZXP Installer ( mac下需要注意将ZXP Installer 放到应用程序中才能生效 )

3.解压后找到 build/extension/中的bodymovin.zxp 拖拽到ZXP Installer中安装,成功后打开AE,勾选 首选项/常规/允许脚本写入文件和访问网络。

4.在AE/窗口/扩展中打开bodymovin,在bodymovin面板中设置好导出目录,然后点击Render按钮一键导出json文件以及相关的图片。

lottile使用

lottile的web端使用ts来包装的 我们可以结合ts声明文件可以很容易就了解其用法

export type AnimationDirection = 1 | -1;//播放方向
export type AnimationSegment = [number, number];
export type AnimationEventName = 'enterFrame' | 'loopComplete' | 'complete' | 'segmentStart' | 'destroy' | 'config_ready' | 'data_ready' | 'DOMLoaded' | 'error';
export type AnimationEventCallback<T = any> = (args: T) => void;

export type AnimationItem = {
    play(): void;//播放动画
    stop(): void;//停止动画
    pause(): void;//暂停动画
    resize(): void; 
    setLocationHref(href: string): void;
    setSpeed(speed: number): void;
    goToAndPlay(value: number, isFrame?: boolean): void; //跳到某一帧动画,并播放
    goToAndStop(value: number, isFrame?: boolean): void; //跳到某一帧动画,并停止
    setDirection(direction: AnimationDirection): void;//方向
    playSegments(segments: AnimationSegment | AnimationSegment[], forceFlag?: boolean): void;
    setSubframe(useSubFrames: boolean): void;
    destroy(): void;
    getDuration(inFrames?: boolean): number;
    triggerEvent<T = any>(name: AnimationEventName, args: T): void; //触发事件 AnimationEventName
    addEventListener<T = any>(name: AnimationEventName, callback: AnimationEventCallback<T>): void;//监听事件
    removeEventListener<T = any>(name: AnimationEventName, callback: AnimationEventCallback<T>): void;//移除
}

export type BaseRendererConfig = {
    imagePreserveAspectRatio?: string;
    className?: string;
};

export type SVGRendererConfig = BaseRendererConfig & {
    title?: string;
    description?: string;
    preserveAspectRatio?: string;
    progressiveLoad?: boolean;
    hideOnTransparent?: boolean;
    viewBoxOnly?: boolean;
    viewBoxSize?: string;
    focusable?: boolean;
};

export type CanvasRendererConfig = BaseRendererConfig & {
    clearCanvas?: boolean;
    context?: CanvasRenderingContext2D;
    progressiveLoad?: boolean;
    preserveAspectRatio?: string;
};

export type HTMLRendererConfig = BaseRendererConfig & {
    hideOnTransparent?: boolean;
};

export type AnimationConfig = {
    container: Element;//挂载dom
    renderer?: 'svg' | 'canvas' | 'html';//渲染类型
    loop?: boolean | number;//是否循环
    autoplay?: boolean;//是否自动播放
    name?: string;//名字
    rendererSettings?: SVGRendererConfig | CanvasRendererConfig | HTMLRendererConfig;
}

export type AnimationConfigWithPath = AnimationConfig & {
    path?: string;// path设置
}

export type AnimationConfigWithData = AnimationConfig & {
    animationData?: any; //data设置
}

type LottiePlayer = {
    play(name?: string): void; //播放动画
    stop(name?: string): void; //停止播放动画
    setSpeed(speed: number, name?: string): void;//设置播放速度
    setDirection(direction: AnimationDirection, name?: string): void; // 设置播放方向
    searchAnimations(animationData?: any, standalone?: boolean, renderer?: string): void;
    loadAnimation(params: AnimationConfigWithPath | AnimationConfigWithData): AnimationItem;//加载动画,并返回一个 AnimationItem类型
    destroy(name?: string): void;//销毁
    registerAnimation(element: Element, animationData?: any): void; //注册动画
    setQuality(quality: string | number): void;
};

declare const Lottie: LottiePlayer;

export default Lottie;

let item:AnimationItem = lottie.loadAnimation({
  container: element, // the dom element that will contain the animation
  renderer: 'svg',
  loop: true,
  autoplay: true,
  path: 'data.json' // the path to the animation json
});

原理简介

Lottie原理与源码解析 源码分析——svg渲染 在Adobe After Effects中,动画是由一个一个的图层组成的,在相应的图层上面添加一些变换(例如:缩放、移动等),这变成为了动画。

bodymovin插件将AE转为JSON

{
    "fr": 30, // 帧率
    "ip": 0, // 起始关键帧
    "op": 20, // 结束关键帧
    "w": 150, // 视图宽
    "h": 130, // 视图高
    "assets": [], // 资源集合 
    "layers": [{ // 图层
        "ty": 0, // 图层类型。
        "refId": "comp_0", // 引用的资源,图片/预合成层
        "ks": {}, // 变换。对应AE中的变换设置,下面有详细介绍
        layer: [], // 该图层包含的子图层
        shapes: [], // 形状图层
        "w": 1334,
        "h": 750,
        "bm": 0
    }], // 图层集合
    "masker": [] // 蒙层集合
}

layers是个数组,每一项对应AE稿中的图层,每个图层都有对应的相关参数,变换 内容 自图层等

在lottie-web中,会根据上面的json,进行相应的渲染处理:

  • shapes中会有各种形状,lottie-web会根据其参数,渲染出相应的svg标签;
  • ks中会有变换参数,lottie-web会将其转换成相应的trasform属性,添加到对应svg标签上;
  • ks的变换参数可能随时间变换,lottie-web会根据参数,调用window.requestAnimationFrame方法,对transform属性进行动态更新,实现动画。

实际应用

js文件及json文件加载方案的考量

  • 我们不希望json文件打包到工程中,1是因为会引起最后的包的大小,2方便替换图像
  • 建议外链引入 lottie,并统一项目渲染格式,使用最轻对应版本

问题

AE制作相关:

  • 将对应图层命名为#Id格式或.class格式,最终挂载后我们可以通过dom获取对应元素

  • 不支持路径合成,把一些合成的路径关闭

  • 尽量不使用预合成图层,需要将预合成中的所有图层都复制到主面板中,否则预合成中的动画可能会丢失

  • 文字显示问题 lottie对文本支持不好,若出现此问题,可用AI导入

  • 目前Lottie-ios还不支持的After Effects 特性

    • 形状图层填充规则(奇偶/非零缠绕)
    • 合并形状
    • 裁切路径中的个别裁切形状功能
    • 表达式
    • 3D图层
    • 图层样式渐变
    • 多边形形状
    • 反相Alpha蒙板
  • json文件相关:

    • 尽量减小图层,图层数量会直接影响json大小
    • 奖励所有图层都是AE中的,其他软件如AI等导入的可能会导致json变大
    • 可能会有些东西不支持 其他:
  • 若是全屏动画,可能会导致浏览器没有全部遮罩,留白边,建议全屏动画用div包裹一层,自己盖一层蒙层

很漂亮的微动效 https://codepen.io/collection/nVYWZR/?cursor=ZD0wJm89MSZwPTEmdj03MTc3MDk= https://imweb.io/topic/5b23a745d4c96b9b1b4c4efc http://dopro.io/animation-solution-lottie.html

Last Updated: 10/24/2019, 4:46:49 PM