133 lines
2.5 KiB
Vue
133 lines
2.5 KiB
Vue
|
<template>
|
||
|
<div class="async-wrapper" :class="{ 'loaded': loaded }">
|
||
|
<div class="deferred">
|
||
|
<slot></slot>
|
||
|
</div>
|
||
|
<div class="loader-wrapper">
|
||
|
<div class="loader-ellipsis">
|
||
|
<div></div>
|
||
|
<div></div>
|
||
|
<div></div>
|
||
|
<div></div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
|
||
|
export default {
|
||
|
name: 'AsyncLoader',
|
||
|
props: {
|
||
|
loaded: {
|
||
|
type: Boolean,
|
||
|
default: false
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style>
|
||
|
.async-wrapper {
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .deferred {
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
display: none;
|
||
|
}
|
||
|
|
||
|
.async-wrapper.loaded > .deferred {
|
||
|
display: block;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper {
|
||
|
display: flex;
|
||
|
justify-content: center;
|
||
|
align-items: center;
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis {
|
||
|
color: #17a2b8;
|
||
|
}
|
||
|
|
||
|
.async-wrapper.loaded > .loader-wrapper {
|
||
|
display: none;
|
||
|
}
|
||
|
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis,
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis div {
|
||
|
box-sizing: border-box;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis {
|
||
|
display: inline-block;
|
||
|
position: relative;
|
||
|
width: 80px;
|
||
|
height: 80px;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis div {
|
||
|
position: absolute;
|
||
|
top: 33.33333px;
|
||
|
width: 13.33333px;
|
||
|
height: 13.33333px;
|
||
|
border-radius: 50%;
|
||
|
background: currentColor;
|
||
|
animation-timing-function: cubic-bezier(0, 1, 1, 0);
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis div:nth-child(1) {
|
||
|
left: 8px;
|
||
|
animation: loader-ellipsis1 0.6s infinite;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis div:nth-child(2) {
|
||
|
left: 8px;
|
||
|
animation: loader-ellipsis2 0.6s infinite;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis div:nth-child(3) {
|
||
|
left: 32px;
|
||
|
animation: loader-ellipsis2 0.6s infinite;
|
||
|
}
|
||
|
|
||
|
.async-wrapper > .loader-wrapper > .loader-ellipsis div:nth-child(4) {
|
||
|
left: 56px;
|
||
|
animation: loader-ellipsis3 0.6s infinite;
|
||
|
}
|
||
|
|
||
|
@keyframes loader-ellipsis1 {
|
||
|
0% {
|
||
|
transform: scale(0);
|
||
|
}
|
||
|
100% {
|
||
|
transform: scale(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@keyframes loader-ellipsis3 {
|
||
|
0% {
|
||
|
transform: scale(1);
|
||
|
}
|
||
|
100% {
|
||
|
transform: scale(0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@keyframes loader-ellipsis2 {
|
||
|
0% {
|
||
|
transform: translate(0, 0);
|
||
|
}
|
||
|
100% {
|
||
|
transform: translate(24px, 0);
|
||
|
}
|
||
|
}
|
||
|
</style>
|