I have a need to achieve a display with a circle with a text score in it (number 1 to 10) Then around that circle, I would like animate a display that incates a gauge getting fuller starting at 0 moving to the relevant number.
This all works well in all browser except Safari. The moment you zoom in / out, the display breaks and the circles no longer overlap.
We are using CSS transform. Is there any alternative recommendations to achieve something similiar?Sample screen showing the rendering
Here is a sample piece of html to demonstrate the problem in Safari
.doughnut {
transform: translateX(2px);
margin: auto;
}
.score-text {
fill: #ffffff;
}
.score-text.secondary {
fill: #1B3A57;
}
.gradient--start {
stop-color: hsl(209, 52.6%, 85%);
}
.gradient--end {
stop-color: #1B3A57;
}
svg {
cursor: pointer;
}
.circle-chart__background {
stroke: #ffffff;
stroke-width: 6;
fill: #1B3A57;
transition: fill 0.4s ease;
}
.circle-chart__background.secondary {
fill: #eaeaea;
transition: fill 0.4s ease;
margin-left: 4px;
}
.circle-chart__circle {
animation: circle-chart-fill 2s reverse;
transform: rotate(-90deg);
transform-origin: center;
stroke: url(#grad2);
stroke-width: 2;
stroke-linecap: round;
fill: none;
}
.circle-chart__circle--negative {
transform: rotate(-90deg) scale(1, -1);
}
@keyframes circle-chart-fill {
to {
stroke-dasharray: 0 100;
}
}
@keyframes circle-chart-appear {
to {
opacity: 1;
transform: translateY(0);
}
}
html {
font-family: sans-serif;
padding-right: 1em;
padding-left: 1em;
}
<div class="doughnut">
<div>
<svg width="100%" height="100%" viewBox="0 0 42 42" class="doughnut">
<defs>
<linearGradient id="grad2" x1="90%" y1="95%" x2="0%" y2="30%">
<stop offset="0%" class="gradient--start" stop-opacity="1" />
<stop offset="100%" class="gradient--end" />
</linearGradient>
</defs>
<circle
class="circle-chart__background secondary"
cx="19"
r="15.91549431"
cy="23"
/>
<circle
class="circle-chart__circle"
cx="19"
r="15.91549431"
cy="19"
stroke-dasharray="60 40"
v-if="score"
/>
<g class="circle-chart__info">
<text
class="score-text secondary"
x="19"
y="23"
alignment-baseline="central"
text-anchor="middle"
font-size="8"
>
6
</text>
</g>
</svg>
</div>
</div>
Here is a video that demonstrates the issue https://vimeo.com/848865835?share=copy
You're compensating CSS transform
by making your circles excentric.
You might keep circles
concentric at (19, 23) and use transform
attribute on circle
instead:
.doughnut {
transform: translateX(2px);
margin: auto;
}
.score-text {
fill: #ffffff;
}
.score-text.secondary {
fill: #1B3A57;
}
.gradient--start {
stop-color: hsl(209, 52.6%, 85%);
}
.gradient--end {
stop-color: #1B3A57;
}
svg {
cursor: pointer;
}
.circle-chart__background {
stroke: #ffffff;
stroke-width: 6;
fill: #1B3A57;
transition: fill 0.4s ease;
}
.circle-chart__background.secondary {
fill: #eaeaea;
transition: fill 0.4s ease;
margin-left: 4px;
}
.circle-chart__circle {
animation: circle-chart-fill 2s reverse;
stroke: url(#grad2);
stroke-width: 2;
stroke-linecap: round;
fill: none;
}
.circle-chart__circle--negative {
transform: rotate(-90deg) scale(1, -1);
}
@keyframes circle-chart-fill {
to {
stroke-dasharray: 0 100;
}
}
@keyframes circle-chart-appear {
to {
opacity: 1;
transform: translateY(0);
}
}
html {
font-family: sans-serif;
padding-right: 1em;
padding-left: 1em;
}
<div class="doughnut">
<div>
<svg width="100%" height="100%" viewBox="0 0 42 42" class="doughnut">
<defs>
<linearGradient id="grad2" x1="90%" y1="95%" x2="0%" y2="30%">
<stop offset="0%" class="gradient--start" stop-opacity="1" />
<stop offset="100%" class="gradient--end" />
</linearGradient>
</defs>
<circle
class="circle-chart__background secondary"
cx="19"
r="15.91549431"
cy="23"
/>
<circle
class="circle-chart__circle"
cx="19"
r="15.91549431"
cy="23"
stroke-dasharray="60 40"
v-if="score"
transform="rotate(-90, 19, 23)"
/>
<g class="circle-chart__info">
<text
class="score-text secondary"
x="19"
y="23"
alignment-baseline="central"
text-anchor="middle"
font-size="8"
>
6
</text>
</g>
</svg>
</div>
</div>