好记性不如烂笔头,记录一下~
效果:
![](https://i-blog.csdnimg.cn/blog_migrate/e3b7b38d6e4db0e60e0594217a2821bb.jpeg)
代码:
<html>
<head>
<meta charset="UTF-8" />
<title>Test</title>
<style>
.box {
width: 120px;
height: 120px;
position: relative;
}
/*文本展示在svg外,通过position定位*/
/* .text{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
} */
</style>
</head>
<body>
<div class="box">
<!-- 将圆翻转90度,使进度条从顶部开始 -->
<svg id="cirlceSvg" width="100%" height="100%">
<circle id="baseCircle" class="circle" cx="50%" cy="50%" fill="none" />
<circle id="progress" class="circle" cx="50%" cy="50%" fill="none" stroke-linecap="round"
style="transform-origin: center; transform: rotate(-90deg);animation: circleProgress 1s 1;" />
<text x="50%" y="60%" style="text-anchor: middle;">
<tspan id="text"></tspan>
<tspan>%</tspan>
</text>
</svg>
<!-- <div class="text">
<div>
<span id="text"></span>%
</div>
</div> -->
</div>
<script>
var rate = 50;
var unit = '%';
var strokeWidth = 10;
var activeColor = "#3c9cff";
var inActiveColor = "#eee";
var svg = document.getElementById("cirlceSvg");
var width = svg.clientWidth;
var r = (100 - strokeWidth) / 2; // 计算半径百分比
var dasharray = r * 2 * Math.PI; // 2πr 周长
var end = r * 2 * Math.PI * (1 - rate / 100);
// 底部圆环
var circle1 = document.getElementById("baseCircle");
// 设置属性
circle1.setAttribute("r", r + unit);
circle1.setAttribute("stroke-width", strokeWidth + unit);
circle1.setAttribute("stroke", inActiveColor);
var circle2 = document.getElementById("progress");
// 设置属性
circle2.setAttribute("r", r + unit);
circle2.setAttribute("stroke-width", strokeWidth + unit);
circle2.setAttribute("stroke", rate > 0 ? activeColor : inActiveColor);
circle2.setAttribute("stroke-dasharray", dasharray + unit);
circle2.setAttribute("stroke-dashoffset", end + unit);
var text = document.getElementById("text");
text.innerHTML = rate;
// css动画设置
document.styleSheets[0].insertRule(
`
@-webkit-keyframes circleProgress{ from{ stroke-dashoffset: ${dasharray}${unit}; } to { stroke-dashoffset: ${end}${unit}; }}
`,
0
);
</script>
</body>
</html>
思路:大小由外部框子控制,里面全部使用百分比。
画两个大小相同的圆形,内部不填色,利用描边显示环形;
底层圆环设置灰色;
上层圆环设置需要的颜色,本例设置的蓝色;
需要知道的数据,百分比rate,描边宽度strokeWidth,需要计算的数据:
半径:(总宽 度 - 描边宽度) / 2;
stroke-dasharray的破折号长度:周长2πr 2 * Math.PI * r
stroke-dashoffset 偏移量,通过stroke-dasharray和stroke-dashoffset控制蓝边的显示:周长 - 百分比占的周长长度
动态效果用css的动画,控制stroke-dashoffset从最大值stroke-dasharray的值到stroke-dashoffset 偏移量
中间文本可以利用svg文本框添加,也可以直接在svg外加div,利用定位放在svg上;相对来说灵活一些
知识点记录:
svg的circle属性:
cx:圆心x坐标
cy:圆形y坐标
r: 圆半径
fill:填充颜色,none不填充,
stroke-width:描边宽度
stroke:描边颜色
stroke-dasharray:用于绘制以虚线呈现的SVG形状的笔触。之所以称为“破折号数组”,第一个值是破折号长度,第二个值是空白长度
stroke-dashoffse:偏移量
stroke-linecap:描边线帽,round圆角,因为有这个帽子(占一定宽度)的原因,rate为0的时候需要特殊处理一下,上层圈描边颜色改为和底层一致;
![](https://i-blog.csdnimg.cn/blog_migrate/60a509eda2184c4de09710ce02b2ec3c.jpeg)
没帽
![](https://i-blog.csdnimg.cn/blog_migrate/875ba2e6a9d1134ddd696a6c01e1d97f.jpeg)
有圆帽
css用到的属性
transform-origin: center; 沿着中心选择
transform: rotate(-90deg); 逆时针选择90度
![](https://i-blog.csdnimg.cn/blog_migrate/d7435b5f20380ec163b1c8220ecc21ef.jpeg)
不旋转之前
![](https://i-blog.csdnimg.cn/blog_migrate/875ba2e6a9d1134ddd696a6c01e1d97f.jpeg)
旋转之后
animation: circleProgress 1s 1; 动画用1s执行circleProgress 1次
@-webkit-keyframes circleProgress{ from{ stroke-dashoffset: ${dasharray}${unit}; } to { stroke-dashoffset: ${end}${unit}; }} 定义动画