Loading SVG circle (using stroke-dashoffset)
(bonus: loading state)
by jorgeluis
HTML
<div class="container">
<div class="p-1">
<svg class="doughnut" width="100%" height="100%" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="48" class="base-circle" stroke-width="4" />
<circle class="value-circle" cx="50" cy="50" r="48" stroke-width="4"
stroke-dasharray="301.584"
stroke-dashoffset="38.99050285714287"
/>
</svg>
</div>
</div>
<button type="button" id="toggle">
Toggle loading state
</button>
<button type="button" id="reset">
Reset
</button>
CSS
.doughnut {
fill: none;
transform: rotate(-90deg);
}
.base-circle, .value-circle {
fill: none;
}
.base-circle {
stroke: rgba(150, 150, 150, 0.2)
}
.value-circle {
stroke: orange;
transition: stroke-dashoffset 1s;
}
/* loading state animation */
.is-loading .value-circle {
animation: resetDashoffset 2s linear infinite;
opacity: 0.3;
transition: opacity 1s;
stroke: var(--mute-color, #666);
stroke-dasharray: 303;
stroke-dashoffset: 305;
}
.reset .value-circle {
animation: resetDashoffset 1s reverse;
stroke-dasharray: 303;
}
@keyframes resetDashoffset {
to {
stroke-dashoffset: 0;
}
}
@keyframes resetDasharray {
to {
stroke-dashoffset: 0;
}
}
/*
the styles below are only for demo design
*/
body {
background: #191D22
}
.container {
display: flex;
justify-content: space-around;
}
svg {
max-width: 150px;
}
.p-1 {
padding: 1em
}
JavaScript
var toggle = document.querySelector('#toggle');
var reset = document.querySelector('#reset');
var doughnut = document.querySelector('.doughnut');
toggle.addEventListener('click', function() {
doughnut.classList.toggle('is-loading')
})
reset.addEventListener('click', function() {
doughnut.classList.remove('is-loading')
doughnut.classList.toggle('reset')
})