I’m trying to make the element shown in the image below:
It is based on the Apple Watch widget for Air quality.
The circle is not fully round and the gradient changes across the line. Besides that, there is a ‘point’ that shows what the actual value is (I would like to set this with JavaScript).
I tried to make the half circle using dasharray
and dashoffset
. But the gradient I cannot get to cross the full line. I also cannot get the gap of the circle on the bottom without using transform: rotate
on the object.
#Layer_1 {
transform: rotate(135deg);
}
.ring {
stroke-dasharray:314;
stroke-dashoffset: 78;
stroke-linecap: round;
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="500px" height="500px" viewBox="0 0 120 120" enable-background="new 0 0 120 120" xml:space="preserve">
<circle class="ring" fill="none" stroke="url(#linear)" stroke-width="10" stroke-miterlimit="10" cx="50%" cy="50%" r="50"/>
<defs>
<linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="#05a"></stop>
<stop offset="50%" stop-color="#a55"></stop>
<stop offset="100%" stop-color="#0a5"></stop>
</linearGradient>
</defs>
</svg>
2
Answers
While SVG content does not support conical gradients directly, you can combine a HTML element with a
background-image: conic-gradient()
and a SVG-defined mask that cuts out the arc and the position marker.For the arc you can either use your technique with a circle and a
stroke-dasharray
. I find it easier to draw a path with an appropriate arc. ThepathLength
attribute will help in positioning along its length, but is not strictly needed for my solution.There are multiple ways to achieve a progress marker, here I am going with a fake
<animateMotion>
animating a ring along the path that does not really move. The position is set as thekeyPoints="x;x"
attribute, withx
a number between 0 and 1, to be set with Javascript.You are on the right track when it comes to the stroke dash array. In this example the circle and the focus point is made using a mask. The mask is applied to a group containing four different lines that in all makes the circular gradient. I know, the question is not so much about that gradient, but it kind of gets important now that SVG only has linear and radial gradients.