Files
AboutMe/src/components/loadingOverlay.astro
2026-02-02 22:47:52 +03:00

93 lines
2.5 KiB
Plaintext

---
import { siteConfig } from "@/config";
import { i18n } from "@i18n/translation";
import I18nKey from "@i18n/i18nKey";
const config = siteConfig.loadingOverlay;
const showOverlay = config?.enable ?? true;
const showSpinner = config?.spinner?.enable ?? true;
const showTitle = config?.title?.enable ?? true;
const titleContent = config?.title?.content ?? i18n(I18nKey.loading);
const spinnerInterval = config?.spinner?.interval ?? 1.5;
const titleInterval = config?.title?.interval ?? 1.5;
---
{showOverlay && (
<div
id="loading-overlay"
class="fixed inset-0 z-100 flex items-center justify-center bg-(--page-bg) transition-opacity duration-600"
>
<div class="flex flex-col items-center">
<!-- loading icon -->
{showSpinner && <div class="loading-spinner mb-4"></div>}
<!-- loading title -->
{showTitle && (
<div
class="loading-title text-(--primary) font-medium tracking-widest"
>
{titleContent}
</div>
)}
</div>
</div>
)}
<style define:vars={{ spinnerInterval: `${spinnerInterval}s`, titleInterval: `${titleInterval}s` }}>
@keyframes spin {
0% {
rotate: 0deg;
}
100% {
rotate: 360deg;
}
}
@keyframes spinner-glow {
0%,
100% {
box-shadow: 0 0 12px var(--primary);
border-top-color: var(--primary);
}
50% {
box-shadow: 0 0 24px var(--primary);
border-top-color: var(--primary);
}
}
.loading-spinner {
width: 48px;
height: 48px;
border: 3px solid color-mix(in oklch, var(--primary) 10%, transparent);
border-top: 3px solid var(--primary);
border-radius: 50%;
animation:
spin var(--spinnerInterval) linear infinite,
spinner-glow var(--spinnerInterval) ease-in-out infinite;
}
@keyframes text-glow {
0%,
100% {
opacity: 0.6;
text-shadow: 0 0 12px var(--primary);
}
50% {
opacity: 1;
text-shadow: 0 0 24px var(--primary);
}
}
.loading-title {
animation: text-glow var(--titleInterval) ease-in-out infinite;
}
/* 手动触发淡出类 */
#loading-overlay.fade-out {
opacity: 0;
pointer-events: none;
}
/* 当 html 移除 is-loading 类时,确保 overlay 隐藏 */
:global(html:not(.is-loading)) #loading-overlay {
opacity: 0;
pointer-events: none;
}
</style>