<div id="example"></div>
html, body {
background-color: #2962FF;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
position: relative;
}
circle {
transition: stroke-dashoffset 0.35s;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
View Compiled
const ProgressRing = Vue.component('progress-ring', {
props: {
radius: Number,
progress: Number,
stroke: Number
},
data() {
const normalizedRadius = this.radius - this.stroke * 2;
const circumference = normalizedRadius * 2 * Math.PI;
return {
normalizedRadius,
circumference
};
},
computed: {
strokeDashoffset() {
return this.circumference - this.progress / 100 * this.circumference;
}
},
template: `
<svg
:height="radius * 2"
:width="radius * 2"
>
<circle
stroke="white"
:stroke-dasharray="circumference + ' ' + circumference"
:style="{ strokeDashoffset: strokeDashoffset }"
:stroke-width="stroke"
fill="transparent"
:r="normalizedRadius"
:cx="radius"
:cy="radius"
/>
</svg>
`
});
// launch example with progress ring
new Vue({
el: '#example',
components: {
'progress-ring': ProgressRing
},
data() {
return { progress: 0 }
},
mounted() {
// emulating progress
const interval = setInterval(() => {
this.progress += 10;
if (this.progress === 100)
clearInterval(interval);
}, 1000);
},
template: `
<div>
<progress-ring radius="60" :progress="progress" stroke="4"></progress-ring>
</div>
`
});
This Pen doesn't use any external CSS resources.