Animates SVG Donut (doughnut) Chart
by moob
HTML
<svg width="35px" height="34px" viewBox="-1 0 35 34" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 3.8.3 (29802) - http://www.bohemiancoding.com/sketch -->
<desc>Created with Sketch.</desc>
<defs>
<circle id="path-1" cx="16.7813362" cy="16.7813362" r="16.7813362"></circle>
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="33.5626723" height="33.5626723" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<circle id="path-3" cx="16.7813362" cy="16.7813362" r="16.7813362"></circle>
<mask id="mask-4" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="33.5626723" height="33.5626723" fill="white">
<use xlink:href="#path-3"></use>
</mask>
</defs>
<g id="rings" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<use id="backg" stroke="#979797" mask="url(#mask-2)" stroke-width="10" transform="translate(16.781336, 16.781336) rotate(90.000000) translate(-16.781336, -16.781336) " xlink:href="#path-1"></use>
<use id="foreg" stroke="" mask="url(#mask-4)" stroke-width="10" stroke-dasharray="60,100" transform="translate(16.781336, 16.781336) scale(-1, 1) rotate(-180.000000) translate(-16.781336, -16.781336) " xlink:href="#path-3"></use>
</g>
</svg>
<svg id="donutBase" viewBox="0 0 34 34" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Doughnut</title>
<desc>Calculated to have diameter of 100 to make things easy</desc>
<defs>
<circle id="background-ring" cx="16.7813362" cy="16.7813362" r="16.7813362"></circle>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient">
<stop stop-color="#FB0071" offset="0%"></stop>
<stop stop-color="#5C0873" offset="100%"></stop>
...
CSS
#donutBase {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
svg:not(:root) {
overflow: hidden;
}
svg .backg {
stroke: #ccc;
mask: url(#ring-mask);
fill-opacity: 0;
stroke-opacity: 1;
}
svg .foreg {
stroke: url(#linearGradient);
mask: url(#ring-mask);
fill-opacity: 0;
stroke-opacity: 1;
stroke-dasharray: 100px;
transition: stroke-dashoffset 1.5s cubic-bezier(0.25, 0.1, 0.23, 0.97);
}
svg .foreg2 {
stroke: url(#linearGradient2);
mask: url(#ring-mask);
fill-opacity: 0;
stroke-opacity: 1;
stroke-dasharray: 100px;
transition: stroke-dashoffset 1.5s cubic-bezier(0.25, 0.1, 0.23, 0.97);
}
#donutWrapper {
width: 50%;
}
div ~ svg {
width: 100%;
}
#chart2 .backg {
stroke: #fff;
}
#chart3, #chart4, #chart5 {
width: 50px;
}
#chart4 .backg {
stroke: #eee;
}
#chart6 {width:100px;}
/* override a gradient:
#linearGradient2 stop {
stop-color:#005C08;
}
#linearGradient2 stop + stop {
stop-color:#00FB00;
} */
JavaScript
(function() {
var foregs = document.querySelectorAll(".foreg"),
x = document.getElementById("x"),
fnc = function() {
for (i = 0; i < foregs.length; ++i) {
var r = (Math.random() * 100);
foregs[i].setAttribute("stroke-dashoffset", r + "px");
if (foregs[i].nextSibling.nextSibling) {
var nx = foregs[i].nextSibling.nextSibling;
console.log(nx);
nx.setAttribute("stroke-dashoffset", ((r - 100)-1) + "px");
}
}
};
x.addEventListener("click", fnc, false);
})();