lottie-web动画库基础使用

2,469 阅读4分钟

先附上官方文档传送门:lottie-web官方文档 | github

一 什么场景使用lottie动画

实际使用场景主要有以下三种:

1.1 UI设计师直接给到你一个data.json文件与动画demo

data.json文件示例如下:

lottie动画json数据

这种情况,直接把该json文件放入lottiepath配置项中,即可渲染出目标动画效果。效率高,效果好。

1.2 动画中有和业务强相关的可能需要动态实时修改的信息

动画效果中包含着当前页面具体的业务数据,这时候采用lottie渲染,然后再实时更新lottie动画即可。具体可参考:知乎 | 动态修改 Lottie 中的文本 中的示例说明。

1.3 动画比较复杂的场景

对于某些用纯CSS3 实现比较困难的动画效果,gif图片又过大的情况下,可让设计师提供data.json文件。然后在Client端异步渲染处理,不影响主页面的加载,体验效果最佳。

二 如何使用lottie实现动画

lottie加载时机

由上图可知,lottie库体积还是比较大的,属于重型3th库。因此,在web项目,尤其是H5项目中,建议在Client端 + 懒加载 + 分片加载 来使用该库。

具体代码参见末尾,核心代码片段如下:

const loadLottie = async () => {
    if (process.env.BROWSER && !lottie && !lock) {
        lock = true;
        try {
            // lottie-web体积较大,单独分包加载
            lottie = await import(
            /* webpackChunkName: "lottie_web" */
                'lottie-web/build/player/lottie_light.min.js'
            );
            setLoaded(true);
        } catch (err) {
            lock = false;
            sendError(err);
        }
    }
};

SSR兜底动画UI

注意事项:在lottie动画未加载完成前,页面最好能做好css样式兜底。这样用户体验会更好。 举例说明:

比如,对于上面的动画效果,在SSR阶段如果不做额外处理的话,页面就会空白,直到Client阶段lottie动画加载完成后,才如期展示,体验不好。 改进:在SSR时,CSS渲染出一个绿色的圆形的DOM节点,使其与目标lottie动画中的中心圆完全重合。这样的话,SSR直出页面时,不至于一大片留白。具体效果如下图:

可以看到,SSR出页面时,会显示一个“开始检测”的圆形DOM节点(此时没有四周的环绕效果)。进入Client端渲染时,文案更新为“获取中”(此时仍没有四周的环绕效果)。待lottie-web库加载完毕并且svg动画渲染完毕后,动画效果便叠加上去了(四周的环绕效果出来了)。 整体体验流畅,用户交互良好,lottie-web库也没有影响页面的性能。符合预期。 useLottie hooks封装 针对实际业务中的使用场景,封装了一个useLottie.tsx hooks组件,方便业务方快速使用。全部代码如下:

import React, { useRef, useEffect, useState } from 'react';

let lottie = null;
let lock = false;

interface IConfig {
    /* 用来给动画容器添加样式 */
    className?: string;
    /* loadAnimation()方法的配置参数 */
    [key: string]: any;
}

/**
 * lottie动画hooks简易封装
 * @param animPath 动画数据data.json的路径
 * @param config 额外配置
 */
function useLottie(animPath: string, config: IConfig) {
    const lottieRef = useRef(null);
    const [loaded, setLoaded] = useState(false);
    // 渲染出来的svg动画DOM实例
    const [animInstance, setAnimInstance] = useState(null);

    const { className, ...animParams } = config || {};

    const loadLottie = async () => {
        if (process.env.BROWSER && !lottie && !lock) {
            lock = true;
            try {
                // lottie-web体积较大,单独分包加载
                lottie = await import(
                /* webpackChunkName: "lottie_web" */
                    'lottie-web/build/player/lottie_light.min.js'
                );
                setLoaded(true);
            } catch (err) {
                lock = false;
                console.error(err);
            }
        }
    };

    loadLottie();

    useEffect(() => {
        // loaded表示lottie-web库加载完毕,lottie表示已有该实例
        if (loaded || lottie) {
            const inst = lottie.loadAnimation({
                wrapper: lottieRef.current,
                animType: 'svg',
                // 默认动画循环播放
                loop: true,
                // 动画json数据
                path: animPath,
                ...animParams,
            });
            setAnimInstance(inst);
        }
    }, [loaded]);

    /**
     * 动画DOM渲染函数
     */
    const renderAnimWrap = () => <div ref={lottieRef} className={className} />;

    return [
        renderAnimWrap,
        animInstance,
    ];
}

export default useLottie;

三 如何更新lottie动画

背景

如上图所示,其实圈出来的部分是一个有动画效果的背景。上图四种场景下,动画都是一样的,唯一不同的便是背景颜色。 UI设计师给到了一个data.json文件,如果只使用data.json文件渲染动画,无法满足四种背景色的需求。所以,需要动态更新lottie动画的背景色。 所以,问题来了:如何动态修改lottie中的文本、颜色呢? 两种方案 具体可参考:知乎 | 动态修改 Lottie 中的文本

两种方法:

1,引入lottie-api库

参考:www.jianshu.com/p/6da067816…

2,原生操作生成后的DOM动画

原理如上图,直接锁定目标DOM元素,然后更改其 fill 值,背景色即可更新。