整理了一些CSS自定义加载动画效果,可与遮罩层一起使用

282 阅读1分钟

1.在这里整理了一些PC端的loading动画效果,个人感觉还可以,所以就整理了一下。因为我用的是 Nuxt.js ,所以整理的也是vue组件。 先上效果图,我只整理了原链接的第 1 ,4,5,6,7,8种动画效果。解释一下为什么未收录第2,3种动画,是因为这种动画效果的实现是需要背景色 background-color 存在且不能为透明色的背景色,为透明色的无法遮盖住动画轨迹,而这里遮罩层是需要透明色,所以未采用这两种效果,如果有背景色存在且不透明的童鞋可以考虑添加进来,组件源码就在下面

image.png

<template>
 <div class="spinner" v-if="show">
   <div
     v-for="(item,index) in arr"
     :key="index"
     v-if="index == useIcon"
     :class="'load-'+item"
   >Loading</div>
 </div>
</template>

<script>
export default {
 name: "loading",
 props: {
   maskFlag: {
     type: Boolean // 遮罩层显示开关控制
   },
   spinner: {
     type: Boolean, // 是否需要加载动画
     default() {
       return true; // 默认存在加载动画
     }
   },
   icon: {
     type: Number, // 加载动画图标类型  0 - 1 - 2 - 3 - 4 - 5 -   六种加载动画
     default() {
       return 0; // 默认加载动画类型 0
     }
   }
 },
 data() {
   return {
     show: false, // 加载动画开关
     arr: ["one", "two", "three", "four", "five", "six"] // 加载动画种类数组
   };
 },
 watch: {
   // 监听开关的变化
   maskFlag(newVal, oldVal) {
     // 判断遮罩层是否 打开 / 隐藏 状态   默认是不显示遮罩层
     if (newVal) {
       this.showMask();
       if (this.spinner) {
         // 判断在遮罩层中是否需要加载动画, 不需要则不显示load动画,只显示遮罩层
         this.show = true;
       }
     } else {
       this.hiddenMask();
       if (this.spinner) {
         this.show = false;
       }
     }
   }
 },
 computed: {
   bodyEl() {
     return document.getElementsByTagName("body")[0];
   },
   // 判断开发者传入的数据是否符合条件
   useIcon() {
     if (this.icon >= 0 && this.icon <= this.arr.length - 1) {
       return this.icon;
     } else {
       console.warn(
         `请传入正确的icon类型数值,应为 0~${this.arr.length - 1} 之间`
       );
       return 0;
     }
   }
 },
 methods: {
   showMask() {
     // 创建遮罩层元素
     let mask = document.getElementById("own-mask");
     mask.setAttribute("class", "mask");
   },
   hiddenMask() {
     //隐藏遮罩层元素
     let mask = document.getElementById("own-mask");
     mask.setAttribute("class", "mask-hidden");
   },
   createMask() {
     // 初始化将遮罩层 append 至 body 最外层 ,此处自己可修改 append 位置
     let mask = document.createElement("div");
     mask.className = "mask-hidden";
     mask.setAttribute("id", "own-mask");
     this.bodyEl.appendChild(mask);
   }
 },
 mounted() {
   if (process.client) { // 这里的判断条件是 nuxt.js 所需的,不是 nuxt 项目不要用这个判断
     this.createMask();
   }
 }
};
</script>

<style lang="scss">
.mask {
 width: 100%;
 height: 100%;
 background: rgba(0, 0, 0, 0.3);
 position: fixed;
 left: 0;
 top: 0;
}
.mask-hidden {
 display: none;
}
</style>
<style lang="scss" scoped>
.spinner {
 position: fixed;
 left: 50%;
 top: 50%;
 transform: translate(-50%, -50%);
 z-index: 100;
}
.load-one,
.load-one:before,
.load-one:after {
 background: #ffffff;
 -webkit-animation: load1 1s infinite ease-in-out;
 animation: load1 1s infinite ease-in-out;
 width: 1em;
 height: 4em;
}
.load-one {
 color: #ffffff;
 text-indent: -9999em;
 margin: 88px auto;
 position: relative;
 font-size: 11px;
 -webkit-transform: translateZ(0);
 -ms-transform: translateZ(0);
 transform: translateZ(0);
 -webkit-animation-delay: -0.16s;
 animation-delay: -0.16s;
}
.load-one:before,
.load-one:after {
 position: absolute;
 top: 0;
 content: "";
}
.load-one:before {
 left: -1.5em;
 -webkit-animation-delay: -0.32s;
 animation-delay: -0.32s;
}
.load-one:after {
 left: 1.5em;
}

.load-two {
 color: #fff;
 font-size: 20px;
 margin: 100px auto;
 width: 1em;
 height: 1em;
 border-radius: 50%;
 position: relative;
 text-indent: -9999em;
 -webkit-animation: load2 1.3s infinite linear;
 animation: load2 1.3s infinite linear;
 -webkit-transform: translateZ(0);
 -ms-transform: translateZ(0);
 transform: translateZ(0);
}

.load-three {
 margin: 100px auto;
 font-size: 25px;
 width: 1em;
 height: 1em;
 border-radius: 50%;
 position: relative;
 text-indent: -9999em;
 -webkit-animation: load3 1.1s infinite ease;
 animation: load3 1.1s infinite ease;
 -webkit-transform: translateZ(0);
 -ms-transform: translateZ(0);
 transform: translateZ(0);
}

.load-four {
 color: #ffffff;
 font-size: 90px;
 text-indent: -9999em;
 overflow: hidden;
 width: 1em;
 height: 1em;
 border-radius: 50%;
 margin: 72px auto;
 position: relative;
 -webkit-transform: translateZ(0);
 -ms-transform: translateZ(0);
 transform: translateZ(0);
 -webkit-animation: load4 1.7s infinite ease, round 1.7s infinite ease;
 animation: load4 1.7s infinite ease, round 1.7s infinite ease;
}
.load-five,
.load-five:before,
.load-five:after {
 border-radius: 50%;
 width: 2.5em;
 height: 2.5em;
 -webkit-animation-fill-mode: both;
 animation-fill-mode: both;
 -webkit-animation: load5 1.8s infinite ease-in-out;
 animation: load5 1.8s infinite ease-in-out;
}
.load-five {
 color: #ffffff;
 font-size: 10px;
 margin: 80px auto;
 position: relative;
 text-indent: -9999em;
 -webkit-transform: translateZ(0);
 -ms-transform: translateZ(0);
 transform: translateZ(0);
 -webkit-animation-delay: -0.16s;
 animation-delay: -0.16s;
}
.load-five:before,
.load-five:after {
 content: "";
 position: absolute;
 top: 0;
}
.load-five:before {
 left: -3.5em;
 -webkit-animation-delay: -0.32s;
 animation-delay: -0.32s;
}
.load-five:after {
 left: 3.5em;
}
.load-six,
.load-six:after {
 border-radius: 50%;
 width: 10em;
 height: 10em;
}
.load-six {
 margin: 60px auto;
 font-size: 10px;
 position: relative;
 text-indent: -9999em;
 border-top: 1.1em solid rgba(255, 255, 255, 0.2);
 border-right: 1.1em solid rgba(255, 255, 255, 0.2);
 border-bottom: 1.1em solid rgba(255, 255, 255, 0.2);
 border-left: 1.1em solid #ffffff;
 -webkit-transform: translateZ(0);
 -ms-transform: translateZ(0);
 transform: translateZ(0);
 -webkit-animation: load6 1.1s infinite linear;
 animation: load6 1.1s infinite linear;
}

@keyframes load1 {
 0%,
 80%,
 100% {
   box-shadow: 0 0;
   height: 4em;
 }
 40% {
   box-shadow: 0 -2em;
   height: 5em;
 }
}

@keyframes load2 {
 0%,
 100% {
   box-shadow: 0 -3em 0 0.2em, 2em -2em 0 0em, 3em 0 0 -1em, 2em 2em 0 -1em,
     0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 0;
 }
 12.5% {
   box-shadow: 0 -3em 0 0, 2em -2em 0 0.2em, 3em 0 0 0, 2em 2em 0 -1em,
     0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
 }
 25% {
   box-shadow: 0 -3em 0 -0.5em, 2em -2em 0 0, 3em 0 0 0.2em, 2em 2em 0 0,
     0 3em 0 -1em, -2em 2em 0 -1em, -3em 0 0 -1em, -2em -2em 0 -1em;
 }
 37.5% {
   box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 0, 2em 2em 0 0.2em,
     0 3em 0 0em, -2em 2em 0 -1em, -3em 0em 0 -1em, -2em -2em 0 -1em;
 }
 50% {
   box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 0em,
     0 3em 0 0.2em, -2em 2em 0 0, -3em 0em 0 -1em, -2em -2em 0 -1em;
 }
 62.5% {
   box-shadow: 0 -3em 0 -1em, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
     0 3em 0 0, -2em 2em 0 0.2em, -3em 0 0 0, -2em -2em 0 -1em;
 }
 75% {
   box-shadow: 0em -3em 0 -1em, 2em -2em 0 -1em, 3em 0em 0 -1em, 2em 2em 0 -1em,
     0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0.2em, -2em -2em 0 0;
 }
 87.5% {
   box-shadow: 0em -3em 0 0, 2em -2em 0 -1em, 3em 0 0 -1em, 2em 2em 0 -1em,
     0 3em 0 -1em, -2em 2em 0 0, -3em 0em 0 0, -2em -2em 0 0.2em;
 }
}
@keyframes load3 {
 0%,
 100% {
   box-shadow: 0em -2.6em 0em 0em #ffffff,
     1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
     2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
     1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
     0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
     -2.6em 0em 0 0em rgba(255, 255, 255, 0.5),
     -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7);
 }
 12.5% {
   box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7),
     1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
     1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
     0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
     -2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5);
 }
 25% {
   box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5),
     1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff,
     1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
     0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
     -2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
 }
 37.5% {
   box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
     1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5),
     2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff,
     0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
     -2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
 }
 50% {
   box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
     1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
     2.5em 0em 0 0em rgba(255, 255, 255, 0.5),
     1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff,
     -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
     -2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
 }
 62.5% {
   box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
     1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
     2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
     1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5),
     0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff,
     -2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
 }
 75% {
   box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
     1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
     2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
     1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
     0em 2.5em 0 0em rgba(255, 255, 255, 0.5),
     -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff,
     -1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
 }
 87.5% {
   box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
     1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
     2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
     1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
     0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
     -1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5),
     -2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
 }
}
@keyframes load4 {
 0% {
   box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em,
     0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
 }
 5%,
 95% {
   box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em,
     0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
 }
 10%,
 59% {
   box-shadow: 0 -0.83em 0 -0.4em, -0.087em -0.825em 0 -0.42em,
     -0.173em -0.812em 0 -0.44em, -0.256em -0.789em 0 -0.46em,
     -0.297em -0.775em 0 -0.477em;
 }
 20% {
   box-shadow: 0 -0.83em 0 -0.4em, -0.338em -0.758em 0 -0.42em,
     -0.555em -0.617em 0 -0.44em, -0.671em -0.488em 0 -0.46em,
     -0.749em -0.34em 0 -0.477em;
 }
 38% {
   box-shadow: 0 -0.83em 0 -0.4em, -0.377em -0.74em 0 -0.42em,
     -0.645em -0.522em 0 -0.44em, -0.775em -0.297em 0 -0.46em,
     -0.82em -0.09em 0 -0.477em;
 }
 100% {
   box-shadow: 0 -0.83em 0 -0.4em, 0 -0.83em 0 -0.42em, 0 -0.83em 0 -0.44em,
     0 -0.83em 0 -0.46em, 0 -0.83em 0 -0.477em;
 }
}

@keyframes round {
 0% {
   -webkit-transform: rotate(0deg);
   transform: rotate(0deg);
 }
 100% {
   -webkit-transform: rotate(360deg);
   transform: rotate(360deg);
 }
}
@keyframes load5 {
 0%,
 80%,
 100% {
   box-shadow: 0 2.5em 0 -1.3em;
 }
 40% {
   box-shadow: 0 2.5em 0 0;
 }
}
@keyframes load6 {
 0% {
   -webkit-transform: rotate(0deg);
   transform: rotate(0deg);
 }
 100% {
   -webkit-transform: rotate(360deg);
   transform: rotate(360deg);
 }
}
</style>

挂载成全局组件后,就可以在 .vue 文件中直接使用了

<!-- 根据自己的需求可以去添加不同的功能 -->
<loading :maskFlag="flag" :spinner="true" :icon="5"></loading>

loading效果传送门