VibeGame / src /lib /components /layout /LoadingScreen.svelte
dylanebert's picture
initial commit
794cf6c
<script lang="ts">
import { onMount } from 'svelte';
import { gsap } from 'gsap';
export let loading = true;
let container: HTMLDivElement;
let spinner: HTMLDivElement;
let fadeOut = false;
onMount(() => {
const tl = gsap.timeline();
tl.from('.loading-title', {
opacity: 0,
y: 10,
duration: 0.3,
ease: 'power3.out'
})
.from('.spinner', {
opacity: 0,
scale: 0.8,
duration: 0.2,
ease: 'power3.out'
}, '-=0.1');
gsap.to(spinner, {
rotation: 360,
duration: 1,
repeat: -1,
ease: 'none'
});
return () => {
tl.kill();
gsap.killTweensOf(spinner);
};
});
$: if (!loading && container && !fadeOut) {
fadeOut = true;
gsap.to(container, {
opacity: 0,
duration: 0.25,
ease: 'power2.inOut',
onComplete: () => {
container.style.display = 'none';
}
});
}
</script>
{#if loading || fadeOut}
<div bind:this={container} class="loading-screen">
<div class="loading-content">
<h1 class="loading-title">VibeGame</h1>
<div bind:this={spinner} class="spinner">
<div class="spinner-ring"></div>
<div class="spinner-ring"></div>
<div class="spinner-ring"></div>
</div>
</div>
</div>
{/if}
<style>
.loading-screen {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #0B0A09;
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
}
.loading-content {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 2.5rem;
}
.loading-title {
font-size: 2.5rem;
font-weight: 200;
margin: 0;
color: #ffffff;
letter-spacing: -0.02em;
}
.spinner {
position: relative;
width: 40px;
height: 40px;
}
.spinner-ring {
position: absolute;
width: 100%;
height: 100%;
border: 2px solid transparent;
border-radius: 50%;
border-top-color: #ffffff;
opacity: 0.3;
}
.spinner-ring:nth-child(1) {
animation: spin 1.5s linear infinite;
}
.spinner-ring:nth-child(2) {
width: 80%;
height: 80%;
top: 10%;
left: 10%;
border-top-color: #ffffff;
opacity: 0.5;
animation: spin 1.2s linear infinite reverse;
}
.spinner-ring:nth-child(3) {
width: 60%;
height: 60%;
top: 20%;
left: 20%;
border-top-color: #ffffff;
opacity: 0.8;
animation: spin 0.9s linear infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
</style>