lottie 动画效果实现及性能优化,将 json 文件缓存至 localStorage 中

lottie 动画效果实现及性能优化 前言 官网入口 一、动画效果实现 1、MyLottie 封装成一个公共组件 < template > < div : id = "id" style = "display: inline-block;v...

这篇文章已从掘金同步到个人博客,原始发布地址为 掘金原文

lottie 动画效果实现及性能优化

前言

官网入口

一、动画效果实现

1、MyLottie 封装成一个公共组件

<template>
    <div :id="id" style="display: inline-block;vertical-align: middle;"></div>
</template>

<script>
import lottie from "lottie-web";
export default {
    name: "MyLottie",
    data() {
        return {
            id:`lottie_${Math.uuidFast("")}`
        };
    },
    props:{
        path:{
            type: String,
            default: ""
        },
        loop: {
            type: Boolean,
            default: false
        }
    },
    mounted() {
        console.log(lottie);
        lottie.loadAnimation({
            container: document.getElementById(this.id),
            renderer: "svg", // 渲染方式svg
            ...Object.assign({
                loop: this.loop, // 是否循环
                autoplay: true, // 是否自动播放
                path: this.path
            }, this.$attrs)
        });
    },
    created() {
    },
    methods: {
    }
};
</script>

<style scoped lang="less">

</style>

2、使用这个公共组件

<template>
    <div>
        <my-lottie autoplay="false" :path="path" :loop="true" style="cursor: pointer;font-size: 0"></my-lottie>
    </div>
</template>

import MyLottie from "_c/MyLottie";
export default {
    name: "Home",
    components:{ MyLottie },
    data() {
        return {
            path: "https://gitee.com/lingxiu5858/assets/blob/master/json/lottie_deleteMember.json"
        };
    },
}

二、性能优化

1、公共组件性能优化

<template>
    <div :id="id" style="display: inline-block;vertical-align: middle;"></div>
</template>

<script>
import lottie from "lottie-web";
export default {
    name: "MyLottie",
    title: "这里是页面或组件名字",
    data() {
        return {
            id:`lottie_${Math.uuidFast("")}`
        };
    },
    props:{
        animationJSON:[String, Object]
    },
    mounted() {
        this.loadAnimation();
    },
    created() {
    },
    methods: {
        loadAnimation(){
            let { animationJSON } = this;
            let lottieBox = null;

            // loop: 是否循环 autoplay: 是否自动播放
            let animationParams = { loop: false, autoplay: true };

            /**
             * 根据传进来的类型,设置不同的属性,
             * path 传 JSON文件路径,animationData 传JSON数据,与path互斥
             */
            if(Object.prototype.toString.call(animationJSON) === "[object String]"){
                animationParams.path = animationJSON;
            }else{
                animationParams.animationData = animationJSON;
            }

            console.log("加载动画需要的参数", animationParams);
            lottieBox = lottie.loadAnimation({
                container: document.getElementById(this.id), 
                renderer: "svg", // 渲染方式svg
                ...Object.assign(animationParams, this.$attrs)
            });

            // DOMLoaded DOM元素加载完成时触发
            lottieBox["addEventListener"]("DOMLoaded", () => {
                let animationData = JSON.stringify(lottieBox.animationData); // json动画资源
                if(Object.prototype.toString.call(animationJSON) === "[object String]"){
                    localStorage.setItem(lottieBox.fileName, animationData);
                }
            });
        }
    }
};
</script>

<style scoped lang="less">

</style>

2、外部使用优化后的公共组件

<template>
    <div>
        <button @click="openAnimation" />
        <my-lottie autoplay="false" :path="path" :loop="true" :animationJSON="animationJSON" style="cursor: pointer;font-size: 0"></my-lottie>
    </div>
</template>

import MyLottie from "_c/MyLottie";
export default {
    name: "Home",
    components:{ MyLottie },
        data() {
            return {
        path: "https://gitee.com/lingxiu5858/assets/blob/master/json/lottie_deleteMember.json"
            };
    },
        methods: {
            openAnimation(){
                    this.animationJSON = this.getStorage(this.path);
            },
            /**
             * 检查 Storage 中是否缓存动画
             */
            getStorage(path){
                    // 获取 url 文件名, 并根据文件名检查 Storage 中是否存在
                    let arr = path.split("/");
                    let fileName = arr[arr.length - 1].split(".")[0];
                    let localStorageAnimation = localStorage.getItem(fileName);
                    // localStorage 存在当前动画资源,直接使用; 否则返回 path 地址加载资源
                    return localStorageAnimation ? JSON.parse(localStorageAnimation) : path;
            },
        }
    }