All posts
Synced from Juejin2022-09-123 min read

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

lottie 动画效果实现及性能优化 前言 官网入口 一、动画效果实现 1、MyLottie 封装成一个公共组件 2、使用这个公共组件 二、性能优化 1、公共组件性能优化 2、外部使用优化后的公共组件

SynopsisThis post is preserved inside the rebuilt blog shell while keeping the original Chinese content intact.Original source

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;
            },
        }
    }