SVG - Percent Ring
Jump to navigation
Jump to search
About
NOTE: This page is a daughter page of: SVG and JavaScript
Percentage or progress rings look pretty sexy, but it's a little tricky (not impossible) to do a ring in pure CSS.... so here's a nice solution using Scalable Vector Graphics (SVG) and JavaScript.
Percent Ring with SVG and JavaScript
<!doctype html>
<!--
BIG ACKNOWLEDGMENT:
This expands on the great example from:
https://css-tricks.com/building-progress-ring-quickly/
!-->
<html>
<head>
<meta charset="UTF-8">
<title>Progress Ring Demo</title>
<script>
/**
* Sets the value of a SVG percent ring.
* @param {number} percent The percent value to set.
*/
function setPercentRing(percent) {
var svg = document.getElementById('id-percent-ring-1');
console.log(svg);
var circle = svg.querySelector('circle');
var radius = circle.r.baseVal.value;
var circumference = radius * 2 * Math.PI;
circle.style.strokeDasharray = `${circumference} ${circumference}`;
circle.style.strokeDashoffset = `${circumference}`;
const offset = circumference - percent / 100 * circumference;
circle.style.strokeDashoffset = -offset; // Set to positive for clockwise.
var text = svg.querySelector('text');
text.textContent = String(percent) + '%';
}
</script>
<style>
.big-button {
background-color: #4CAF50; /* Green */
border: none;
color: white;
text-align: center;
text-decoration: none;
font-size: 16px;
}
.percent-ring {
}
.percent-ring-circle {
transition: 0.35s stroke-dashoffset;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
.circle-percent-text {
font-weight: bold;
font-family: "Segoe UI", Arial, sans-serif;
}
</style>
</head>
<body>
<button type="button" class="big-button" onclick="setPercentRing(Math.round(Math.random() * 100));">Randomize</button>
<svg
id="id-percent-ring-1"
class="percent-ring"
width="100%"
height="220">
<circle
class="percent-ring-circle"
stroke="forestgreen"
stroke-width="15"
fill="transparent"
r="90" // Set radius slightly less than height/2.
cx="50%"
cy="50%">
</circle>
<text
x="50%"
y="50%"
dominant-baseline="middle"
text-anchor="middle"
font-size="60px"
class="circle-percent-text" // You can also set text properties in CSS (or a mix).
fill="forestgreen">0%</text>
</svg>
<svg
id="id-circle-1"
width="200"
height="100">
// Add a circle in the middle:
<circle
stroke="rgba(255.0,0,0,0.3)"
stroke-width="15"
fill="transparent"
r="40" // We set radius slightly less than height/2.
cx="50%" cy="50%">
</circle>
// Make a rectangle and move it to the middle and rotate it:
<rect
width="60" height="10"
x="0" y="0"
rx="3" ry="3" // Rounded edges.
// Translate it to the middle of the circle
// then rotate about the middle:
transform="translate(70, 45) rotate(45, 30, 5)"
style="fill:rgba(255,0,0,0.3); stroke-width:1; stroke:rgba(255,0,0,1.0)">
</rect>
// Let's center text in the middle:
<text
x="50%" y="50%"
dominant-baseline="middle" text-anchor="middle"
font-size="30px" fill="#333333"
class="circle-percent-text" // You can also use CSS (or a mix).
>SVG Rocks!</text>
// Now create a poly line with the M (move to) command.
// Note that lower case is for relative (l = line),
// and uppercase would be for an absolute position.
<path id="lineAB" d="M 0 80 l 30 15 30 -15" stroke="red"
stroke-width="5" fill="none" />
// Now create a curved Bézier path:
// M (start_x start_y) q (rel_curve_target_x rel_curve_target_y rel_end_x rel_end_y).
<path d="M 140 80 q 15 20 30 0 q 15 -20 30 0" stroke="blue" stroke-width="5" fill="#0000ff33"/>
</svg>
</body>
</html>
Links
- Building a Progress Ring, Quickly - Great tutorila by Jeremias Menichelli on which this code was based.
- CSS radial progress bar - CSS solution to this by Anders Ingemann.