use svg animation for spinner

This commit is contained in:
Joseph Montanaro 2023-08-06 17:26:54 -07:00
parent 60c24e3ee4
commit 23623ae15b
3 changed files with 36 additions and 102 deletions

View File

@ -1,113 +1,47 @@
<script> <script>
export let color = 'base-content'; import { onMount } from 'svelte';
export let thickness = '2px'; export let thickness = 8;
let classes = ''; let classes = '';
export { classes as class }; export { classes as class };
const colorVars = { const radius = (100 - thickness) / 2;
'primary': 'p', // the px are fake, but we need them to satisfy css calc()
'primary-focus': 'pf', const circumference = `${2 * Math.PI * radius}px`;
'primary-content': 'pc',
'secondary': 's',
'secondary-focus': 'sf',
'secondary-content': 'sc',
'accent': 'a',
'accent-focus': 'af',
'accent-content': 'ac',
'neutral': 'n',
'neutral-focus': 'nf',
'neutral-content': 'nc',
'base-100': 'b1',
'base-200': 'b2',
'base-300': 'b3',
'base-content': 'bc',
'info': 'in',
'info-content': 'inc',
'success': 'su',
'success-content': 'suc',
'warning': 'wa',
'warning-content': 'wac',
'error': 'er',
'error-content': 'erc',
}
let arcStyle = `border-width: ${thickness};`; let spinner;
arcStyle += `border-color: hsl(var(--${colorVars[color]})) transparent transparent transparent;`; onMount(() => {
spinner.style.setProperty('--circumference', circumference);
})
</script> </script>
<svg bind:this={spinner} id="spinner" class={classes} viewBox="0 0 100 100" stroke="currentColor">
<circle cx="50" cy="50" r={radius} stroke-width={thickness} />
</svg>
<style> <style>
#spinner { #spinner {
position: relative; --circumference: 289.0265px;
}
animation: spin; circle {
animation-duration: 1.5s; fill: transparent;
animation-iteration-count: infinite; stroke-dasharray: var(--circumference);
animation-timing-function: linear; transform: rotate(-90deg);
transform-origin: center;
animation: chase 3s infinite,
spin 1.5s linear infinite;
}
@keyframes chase {
0% { stroke-dashoffset: calc(-1 * var(--circumference)); }
50% { stroke-dashoffset: calc(-2 * var(--circumference)); }
100% { stroke-dashoffset: calc(-3 * var(--circumference)); }
} }
@keyframes spin { @keyframes spin {
50% { transform: rotate(225deg); } 50% { transform: rotate(135deg); }
100% { transform: rotate(360deg); } 100% { transform: rotate(270deg); }
}
.arc {
position: absolute;
top: 0;
left: 0;
border-radius: 9999px;
}
.arc-top {
transform: rotate(-45deg);
}
.arc-right {
animation: spin-right;
animation-duration: 3s;
animation-iteration-count: infinite;
}
.arc-bottom {
animation: spin-bottom;
animation-duration: 3s;
animation-iteration-count: infinite;
}
.arc-left {
animation: spin-left;
animation-duration: 3s;
animation-iteration-count: infinite;
}
@keyframes spin-top {
0% { transform: rotate(-45deg); }
50% { transform: rotate(315deg); }
100% { transform: rotate(-45deg); }
}
@keyframes spin-right {
0% { transform: rotate(45deg); }
50% { transform: rotate(315deg); }
100% { transform: rotate(405deg); }
}
@keyframes spin-bottom {
0% { transform: rotate(135deg); }
50% { transform: rotate(315deg); }
100% { transform: rotate(495deg); }
}
@keyframes spin-left {
0% { transform: rotate(225deg); }
50% { transform: rotate(315deg); }
100% { transform: rotate(585deg); }
} }
</style> </style>
<div id="spinner" class="w-6 h-6 {classes}">
<div class="arc arc-top w-full h-full" style={arcStyle}></div>
<div class="arc arc-right w-full h-full" style={arcStyle}></div>
<div class="arc arc-bottom w-full h-full" style={arcStyle}></div>
<div class="arc arc-left w-full h-full" style={arcStyle}></div>
</div>

View File

@ -73,8 +73,8 @@
<input type="password" placeholder="Re-enter passphrase" bind:value={confirmPassphrase} class="input input-bordered" on:change={confirm} /> <input type="password" placeholder="Re-enter passphrase" bind:value={confirmPassphrase} class="input input-bordered" on:change={confirm} />
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
{#if saving} {#if saving }
<Spinner class="w-5 h-5" color="primary-content" thickness="2px"/> <Spinner class="w-5 h-5" thickness="12"/>
{:else} {:else}
Submit Submit
{/if} {/if}

View File

@ -69,7 +69,7 @@
<button type="submit" class="btn btn-primary"> <button type="submit" class="btn btn-primary">
{#if saving} {#if saving}
<Spinner class="w-5 h-5" color="primary-content" thickness="2px"/> <Spinner class="w-5 h-5" thickness="12"/>
{:else} {:else}
Submit Submit
{/if} {/if}