MAC / frontend /src /lib /components /Loader.svelte
Aaryan17's picture
chore: upload MAC codebase to HF Space
0e76632 verified
<!-- MAC Loader Component
Usage: <Loader size={140} color="#DF9076" />
-->
<script>
export let size = 140;
export let color = '#DF9076';
$: cx = size / 2;
$: cy = size / 2;
$: outerR = size * 0.36;
$: nodeR = size * 0.058;
$: ringR = size * 0.13;
$: holeR = size * 0.07;
$: sw = size * 0.026;
$: nodes = Array.from({ length: 6 }, (_, i) => {
const angle = (Math.PI / 3) * i - Math.PI / 6;
return {
x: cx + outerR * Math.cos(angle),
y: cy + outerR * Math.sin(angle),
delay: `${i * 0.14}s`,
};
});
$: hexPoints = nodes.map(n => `${n.x.toFixed(2)},${n.y.toFixed(2)}`).join(' ');
// Hex perimeter β‰ˆ 6 Γ— outerR (side = circumradius for regular hex)
$: hexPerim = 6 * outerR;
$: dashLen = hexPerim * 0.22;
$: dashGap = hexPerim - dashLen;
// Spoke length (center β†’ node)
$: spokeLen = outerR;
// Center ring circumference
$: ringCirc = 2 * Math.PI * ringR;
</script>
<div class="mac-loader" style="width:{size}px; height:{size}px;">
<svg
width={size}
height={size}
viewBox="0 0 {size} {size}"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<!-- ── Hex outline (dimmed skeleton) ── -->
<polygon
points={hexPoints}
stroke={color}
stroke-width={sw * 0.6}
fill="none"
stroke-opacity="0.15"
/>
<!-- ── Hex sweep (rotating bright segment) ── -->
<polygon
class="hex-sweep"
points={hexPoints}
stroke={color}
stroke-width={sw * 0.9}
fill="none"
stroke-dasharray="{dashLen} {dashGap}"
style="--perim: {hexPerim}; animation-duration: 2.4s;"
/>
<!-- ── Spokes ── -->
{#each nodes as n, i}
<line
class="spoke"
x1={cx} y1={cy}
x2={n.x} y2={n.y}
stroke={color}
stroke-width={sw * 0.5}
stroke-opacity="0.2"
stroke-linecap="round"
/>
<!-- Traveling dot along spoke -->
<line
class="spoke-pulse"
x1={cx} y1={cy}
x2={n.x} y2={n.y}
stroke={color}
stroke-width={sw * 0.7}
stroke-linecap="round"
stroke-dasharray="{spokeLen * 0.18} {spokeLen}"
style="animation-delay: {n.delay}; --spoke-len: {spokeLen};"
/>
{/each}
<!-- ── Outer nodes ── -->
{#each nodes as n, i}
<!-- Glow ring -->
<circle
class="node-glow"
cx={n.x} cy={n.y}
r={nodeR * 1.9}
fill={color}
fill-opacity="0"
style="animation-delay: {n.delay};"
/>
<!-- Node dot -->
<circle
class="node-dot"
cx={n.x} cy={n.y}
r={nodeR}
fill={color}
fill-opacity="0.4"
style="animation-delay: {n.delay};"
/>
{/each}
<!-- ── Center ring (spinning arc) ── -->
<circle
cx={cx} cy={cy}
r={ringR}
stroke={color}
stroke-width={sw * 0.7}
fill="none"
stroke-opacity="0.15"
/>
<circle
class="center-arc"
cx={cx} cy={cy}
r={ringR}
stroke={color}
stroke-width={sw * 1.1}
fill="none"
stroke-dasharray="{ringCirc * 0.3} {ringCirc * 0.7}"
style="--circ: {ringCirc};"
/>
<!-- ── Center fill ── -->
<circle
class="center-core"
cx={cx} cy={cy}
r={holeR}
fill={color}
/>
</svg>
</div>
<style>
.mac-loader {
display: inline-flex;
align-items: center;
justify-content: center;
}
/* Hex sweep: dash travels around the hexagon */
.hex-sweep {
transform-origin: 50% 50%;
animation: hexSweep 2.4s linear infinite;
}
@keyframes hexSweep {
from { stroke-dashoffset: 0; }
to { stroke-dashoffset: calc(var(--perim) * -1px); }
}
/* Traveling dot along each spoke */
.spoke-pulse {
animation: spokePulse 1.8s ease-in-out infinite;
}
@keyframes spokePulse {
0% { stroke-dashoffset: 0; stroke-opacity: 0; }
10% { stroke-opacity: 0.9; }
80% { stroke-dashoffset: calc(var(--spoke-len) * -1px); stroke-opacity: 0; }
100% { stroke-dashoffset: calc(var(--spoke-len) * -1px); stroke-opacity: 0; }
}
/* Node glow pulse */
.node-glow {
animation: nodeGlow 1.8s ease-in-out infinite;
}
@keyframes nodeGlow {
0%, 100% { fill-opacity: 0; r: 0; }
40% { fill-opacity: 0.18; }
60% { fill-opacity: 0.08; }
}
/* Node dot brightness */
.node-dot {
animation: nodeDot 1.8s ease-in-out infinite;
}
@keyframes nodeDot {
0%, 100% { fill-opacity: 0.25; }
50% { fill-opacity: 1; }
}
/* Center arc rotation */
.center-arc {
transform-origin: 50% 50%;
animation: centerSpin 1.2s linear infinite;
}
@keyframes centerSpin {
from { transform: rotate(-90deg); }
to { transform: rotate(270deg); }
}
/* Center core pulse */
.center-core {
animation: corePulse 1.8s ease-in-out infinite;
}
@keyframes corePulse {
0%, 100% { fill-opacity: 0.7; transform: scale(1); }
50% { fill-opacity: 1; transform: scale(1.15); }
}
</style>