I'm new to SVG and trying to familiarize myself with it. I would like to create a SVG donut with several segments each segments with different color. It's important that the segments should be interactive (meaning if I hover over them they should change color or pop out). The whole donut should appear with a clock animation.
I tried this with a simple circle and set the stroke-dasharray
and stroke-dashoffset
accordingly. The donut appears properly but when I apply the clock animation with CSS it overrides the color of all segments to the color of the last segment. But then I was thinking about if I want each segment to be interactive probably I have to create a circle
svg element for each segment or a create svg arc
s and build my donut that way.
I would appreciate any advice which way should I go. Here's my code so far:
HTML:
<svg id = "circleMenuViewBox" width = "100%" height = "100%" viewBox="-10 -10 100 100">
<defs>
<circle id ="circlemenu" cx="10" cy="10" r="5" stroke-width="3" fill="none" stroke-dasharray="31.4"/>
</defs>
<use href="#circlemenu" stroke="#689689" stroke-dashoffset="0"/>
<use href="#circlemenu" stroke="#83E8BA" stroke-dashoffset="7.85"/>
<use href="#circlemenu" stroke="#B2E6D4" stroke-dashoffset="15.7"/>
<use href="#circlemenu" stroke="#504136" stroke-dashoffset="23.55"/>
</svg>
CSS:
#circlemenu {
fill: none;
stroke-dasharray: 31.4;
stroke-dashoffset: 31.4;
animation: clock-animation 0.2s linear;
animation-fill-mode: forwards;
}
@keyframes clock-animation {
0% {
stroke-dashoffset: 31.4;
}
100% {
stroke-dashoffset: 0;
}
}
Your animation is causing the last circle to overlay all other segments.
Instead of animating the circle definition referenced by all <use>
instances you can create a <mask>
to progressively show the donut chart.
#circleMask {
fill: none;
stroke-dasharray: 31.4;
stroke-dashoffset: 31.4;
animation: clock-animation 0.8s linear;
animation-fill-mode: forwards;
}
@keyframes clock-animation {
0% {
stroke-dashoffset: 31.4;
}
100% {
stroke-dashoffset: 0;
}
}
<svg id="circleMenuViewBox" width="100%" height="100%" viewBox="-10 -10 100 100">
<defs>
<circle id="circlemenu" cx="10" cy="10" r="5" stroke-width="3" fill="none" stroke-dasharray="31.4" />
<mask id="mask" maskUnits="userSpaceOnUse">
<use id="circleMask" class="segment" href="#circlemenu" stroke="#fff" />
</mask>
</defs>
<g mask="url(#mask)">
<use class="segment" href="#circlemenu" stroke="#689689" stroke-dashoffset="0" />
<use class="segment" href="#circlemenu" stroke="#83E8BA" stroke-dashoffset="7.85" />
<use class="segment" href="#circlemenu" stroke="#B2E6D4" stroke-dashoffset="15.7" />
<use class="segment" href="#circlemenu" stroke="#504136" stroke-dashoffset="23.55" />
</g>
</svg>