1
0
mirror of https://github.com/lana-k/sqliteviz.git synced 2026-08-05 07:19:17 +08:00
Files
sqliteviz/src/components/Common/LoadingIndicator.vue
2026-01-15 21:53:12 +01:00

130 lines
2.6 KiB
Vue

<template>
<svg
:class="animationClass"
:height="size"
:width="size"
:viewBox="`0 0 ${size} ${size}`"
>
<circle
class="loader-svg bg"
:style="{ strokeWidth }"
:cx="size / 2"
:cy="size / 2"
:r="radius"
/>
<circle
class="loader-svg front"
:style="{
strokeDasharray: circleProgress,
strokeDashoffset: offset,
strokeWidth
}"
:cx="size / 2"
:cy="size / 2"
:r="radius"
/>
</svg>
</template>
<script>
export default {
name: 'LoadingIndicator',
props: {
progress: {
type: Number,
required: false
},
size: {
type: Number,
required: false,
default: 20
}
},
emits: [],
computed: {
circleProgress() {
const circle = this.radius * 3.14 * 2
const dash = this.progress
? (circle * this.progress) / 100
: (circle * 1) / 3
const space = circle - dash
return `${dash}px, ${space}px`
},
animationClass() {
return this.progress === undefined ? 'loading' : 'progress'
},
radius() {
return this.size / 2 - this.strokeWidth
},
offset() {
return (this.radius * 3.14) / 2
},
strokeWidth() {
return this.size / 10
}
}
}
</script>
<style scoped>
.loader-svg {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
fill: none;
stroke-linecap: round;
stroke: var(--color-accent);
}
.loader-svg.bg {
stroke: var(--color-gray-light-3);
}
.loading .loader-svg.front {
will-change: transform;
animation: fill-animation-loading 1s cubic-bezier(1, 1, 1, 1) 0s infinite;
transform-origin: center;
}
/*
We can't change anything in loading animation except transform, opacity and filter. Because in
our case the Main Thread can be busy and animation will be frozen (e. g. getting a result set
from the web-worker after query execution).
But transform, opacity and filter trigger changes only in the Composite Layer stage in rendering
waterfall. Hence they can be processed only with Compositor Thread while the Main Thread
processes something else.
https://www.viget.com/articles/animation-performance-101-browser-under-the-hood/
*/
@keyframes fill-animation-loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.progress .loader-svg.front {
transition: stroke-dasharray 0.2s;
}
.progress .loader-svg.bg {
animation: bg-animation 1.5s cubic-bezier(1, 1, 1, 1) 0s infinite;
}
@keyframes bg-animation {
0% {
r: 8;
}
50% {
stroke: var(--color-gray-light-2);
r: 9;
}
100% {
r: 8;
}
}
</style>