preface
I made a component of ring progress bar these days. I did it with CSS before, and this time I intend to try to do it with SVG.
Look at a progress bar
It is actually composed of two parts, the first part is the background gray circle, the second part is the blue arc. The two pieces add up to form a circular progress bar.
The code for SVG is also very simple, as follows:
<svg width="240" height="240" viewBox="0 0 200 200">
<circle
cx="100"
cy="100"
r="70"
stroke-width="30"
stroke="#E5E5E5"
fill="none"
></circle>
<circle
cx="100"
cy="100"
r="70"
stroke-width="30"
stroke="#506DFE"
fill="none"
transform="matrix(0, -1, 1, 0, 0, 200)"
stroke-dasharray="219, 439"
></circle>
</svg>
Copy the code
What do the arguments in the code mean?
The gray circle in the first part is easy to understand, and the circle in the second part has more parameters, which create the effect of the circle.
rotating
The default starting point of a circle is to the right, so to change its starting point to a vertex, you need to do a rotation.
There are several ways to write the rotation parameter. The first is to implement it using the rorate.
If you need to rotate(100, 100) by -90 degrees, the transform=”rotate(-90, 100, 100)” parameter is displayed.
Transform =”matrix(0, -1, 1, 0, 0, 200)”. For details, please refer to this article.
The circular arc
Circle is a complete circle, so what do you do to create an arc?
This is done using stroke-dasharray.
In SVG, stroke-dasharray represents stroke as a dashed line. It can contain two values, the first value is the width of the dashed line and the second value is the spacing of the dashed line. If we set the width of the dashed line to the length of the arc and the spacing to exceed the length of the blank arc, the arc effect can be achieved.
For example, to implement a 50% arc, the first value is 50% * 2 * math. PI * r, and the second value is set directly to 2 * math. PI * r, so that the length of the blank arc is sufficient regardless of the variation.
conclusion
In this way, a circular progress bar is formed by adding an arc to a background color circle.
As for some color Settings, the rounded/square corners of the lines are not covered.
Two helper functions that generate the Transform parameter and stroke-dasharray are attached.
- Rotation matrix
interface OriginCoordinate {
x: number;
y: number;
}
const rotateMatrixGenerator = (
rotate: number,
{ x: currentOriginX, y: currentOriginY }: OriginCoordinate,
{ x: transformOriginX, y: transformOriginY }: OriginCoordinate
) => {
const cos = Math.cos((rotate / 180) * Math.PI);
const sin = Math.sin((rotate / 180) * Math.PI);
return `matrix(${cos}.${sin}.${-sin}.${cos}.${transformOriginX - cos * currentOriginX + sin * currentOriginY}.${transformOriginY - sin * currentOriginX - cos * currentOriginY}) `;
};
Copy the code
- The circular arc
const arcGenerator = (
radius: number,
percentage: number,
arcAngle: number = 360) = > {return `${percentage * radius * 2 * Math.PI * (arcAngle / 360)} ${radius * 2 * Math.PI}`;
};
Copy the code