<template> <div class="loading" :style="{height:loadingRadiusVal+'px',loadingRadiusVal+'px'}"> <div v-for="(dotNum, index) in dotNums" :key="index" :style="dotTransform(index, dotNums)"> <span :style="dotAimation(index, dotNums)"></span> </div> </div> </template>
js
<script> export default{ props:{ loadingRadiusVal: { type: Number, default: 100 }, dotRadiusVal: { type: Number, default: 20 }, dotColorVal: { type: String, default: '#f00' }, dotNums: { type: Number, default: 10 } }, data(){ return{ } }, methods:{ dotTransform(idx,dotNums){ let rad = 2 * Math.PI / dotNums * idx; let dotX = Math.cos(rad) * (this.loadingRadiusVal / 2); let dotY = Math.sin(rad) * (this.loadingRadiusVal / 2); return { transform: `translate(${dotX}px,${dotY}px)`,height: this.dotRadiusVal+'px',this.dotRadiusVal+'px'}; }, dotAimation(idx,dotNums){ let delayTime = `${-1*(1+idx)*1/dotNums}s`; return{ animationDelay:delayTime, background:this.dotColorVal } } } } </script>
css
<style> div.loading{ position: relative; margin: 0 auto; font-size: 0; border-radius: 50%; transform-origin: 50%; } div.loading div{ position: absolute; top: 50%; left: 50%; border-radius: 100%; } span{ display: block; border-radius: 50%; width: 100%; height: 100%; animation: ball 1s infinite ease-in-out; } @keyframes ball{ 0%{ opacity: 1; transform: scale(1); } 20%{ opacity: 1; } 80%{ opacity: 0; transform: scale(0); } } </style>