161 lines
3.1 KiB
Vue
161 lines
3.1 KiB
Vue
<template>
|
|
<view
|
|
class="app-loading"
|
|
:class="`app-loading--${variant}`"
|
|
role="status"
|
|
aria-live="polite"
|
|
aria-busy="true"
|
|
>
|
|
<view class="app-loading__emblem" aria-hidden="true">
|
|
<image
|
|
class="app-loading__seal"
|
|
src="/static/assets/foundation/transparent/brand-seal.png"
|
|
mode="aspectFit"
|
|
/>
|
|
<image
|
|
class="app-loading__knot"
|
|
src="/static/assets/foundation/transparent/auth-divider-knot.png"
|
|
mode="aspectFit"
|
|
/>
|
|
</view>
|
|
<text class="app-loading__copy">{{ text }}</text>
|
|
<text v-if="description" class="app-loading__description">{{
|
|
description
|
|
}}</text>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
defineProps({
|
|
variant: {
|
|
type: String,
|
|
default: "page",
|
|
validator: (value) => ["page", "section"].includes(value),
|
|
},
|
|
text: { type: String, default: "正在展开,请稍候…" },
|
|
description: { type: String, default: "" },
|
|
});
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.app-loading {
|
|
z-index: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: #62584c;
|
|
text-align: center;
|
|
}
|
|
.app-loading__emblem {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
.app-loading__seal {
|
|
animation: app-loading-seal-breathe 1.6s ease-in-out infinite;
|
|
}
|
|
.app-loading__knot {
|
|
margin-top: 8rpx;
|
|
opacity: 0.72;
|
|
animation: app-loading-knot-breathe 1.6s ease-in-out infinite;
|
|
}
|
|
.app-loading__copy {
|
|
font-weight: 500;
|
|
letter-spacing: 2rpx;
|
|
}
|
|
.app-loading__description {
|
|
color: #62584c;
|
|
line-height: 1.65;
|
|
}
|
|
|
|
.app-loading--page {
|
|
min-height: 320rpx;
|
|
}
|
|
.app-loading--page .app-loading__seal {
|
|
width: 132rpx;
|
|
height: 136rpx;
|
|
}
|
|
.app-loading--page .app-loading__knot {
|
|
width: 56rpx;
|
|
height: 18rpx;
|
|
}
|
|
.app-loading--page .app-loading__copy {
|
|
margin-top: 22rpx;
|
|
font-size: clamp(17px, 30rpx, 22px);
|
|
}
|
|
.app-loading--page .app-loading__description {
|
|
margin-top: 14rpx;
|
|
font-size: clamp(15px, 24rpx, 18px);
|
|
}
|
|
|
|
.app-loading--section {
|
|
min-height: 180rpx;
|
|
}
|
|
.app-loading--section .app-loading__seal {
|
|
width: 88rpx;
|
|
height: 90rpx;
|
|
}
|
|
.app-loading--section .app-loading__knot {
|
|
width: 42rpx;
|
|
height: 14rpx;
|
|
margin-top: 5rpx;
|
|
}
|
|
.app-loading--section .app-loading__copy {
|
|
margin-top: 14rpx;
|
|
font-size: clamp(15px, 24rpx, 18px);
|
|
}
|
|
.app-loading--section .app-loading__description {
|
|
margin-top: 10rpx;
|
|
font-size: clamp(14px, 22rpx, 17px);
|
|
}
|
|
@keyframes app-loading-seal-breathe {
|
|
0%,
|
|
100% {
|
|
opacity: 0.82;
|
|
transform: scale(0.96);
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
transform: scale(1);
|
|
}
|
|
}
|
|
@keyframes app-loading-knot-breathe {
|
|
0%,
|
|
100% {
|
|
opacity: 0.44;
|
|
}
|
|
50% {
|
|
opacity: 0.76;
|
|
}
|
|
}
|
|
@keyframes app-loading-seal-essential-pulse {
|
|
0%,
|
|
100% {
|
|
opacity: 0.58;
|
|
}
|
|
50% {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
@keyframes app-loading-knot-essential-pulse {
|
|
0%,
|
|
100% {
|
|
opacity: 0.28;
|
|
}
|
|
50% {
|
|
opacity: 0.86;
|
|
}
|
|
}
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.app-loading__seal {
|
|
animation: none;
|
|
transform: none;
|
|
}
|
|
.app-loading__knot {
|
|
animation: none;
|
|
transform: none;
|
|
}
|
|
}
|
|
</style>
|