能用现成组件就用,实现不行再自己写,因为牵扯到上传文件,进度实时出不来,所以只能使用dom元素操作;
1.实现
效果:

上图是100%,如果需要根据百分比显示,我们需要看下代码里面left和right的旋转角度,这个圆实现上,以垂直直径切割,是左右两部分,调整css transform即可。
代码如下:
html
- percentHtml.innerHTML = `<div class="progress">
- <span class="title">span>
- <div class="overlay">div>
- <div class="left" style="transform: rotate(${get_deg(percenNum)?.left_deg}deg);z-index: ${get_deg(percenNum)?.zIndex_left};">div>
- <div class="right" style="transform: rotate(${get_deg(percenNum)?.right_deg}deg);">div>
- div>`
css
- * {
- box-sizing: border-box;
- padding: 0;
- margin: 0;
- }
- .progress {
- width: 20px;
- height: 20px;
- color: #fff;
- border-radius: 50%;
- overflow: hidden;
- position: relative;
- background: #dcdcdc;
- text-align: center;
- line-height: 200px;
- box-shadow: 2px 2px 2px 2px white;
- mask: radial-gradient(transparent 7px, #000 8px);
- -webkit-mask: radial-gradient(transparent 7px, #000 8px)
- }
- .progress .overlay {
- width: 50%;
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- z-index: 1;
- background-color: #dcdcdc;
- }
- .progress .left,
- .progress .right {
- width: 50%;
- height: 100%;
- position: absolute;
- top: 0;
- left: 0;
- border: 10px solid #29b6f6;
- border-radius: 100px 0px 0px 100px;
- border-right: 0;
- transform-origin: right;
- }
2.原理及函数
可以用这个原理实现百分比:
1)0%,left为0deg(z-index为0,因为right在左边,所以需要index为0至在灰色下面),right为0deg;
2)当百分比小于50%且不为0的时候,左边不需要百分比:继续为0度,右边180度是50%,计算出1%是多少度:180 / 50% = 3.6度(度/1%),乘以百分比即可;
3)大于50%,right为180deg,left对应:100%是0deg,z-Index = 10,75%对应-90deg,以此为例,那么计算规律是,75% - 50% = 25%,25 * 3.6 = 90,因为left是逆时针计算,所以需要用180 - 90 = 90,再添加一个符号即可(数学上直接减180结果一样),就是-90deg。
4)100%,left为0deg(z-index=10,覆盖左侧overlay),right为180deg;
如下函数:
- // 定义一个名为get_deg的函数,接收一个名为percent的number类型参数
- const get_deg = (percent: number) => {
- let left_deg = 0; // 初始化左边角度为0
- let right_deg = 0; // 初始化右边角度为0
- let zIndex_left = 0; // 初始化左边zIndex为0
- const one_percent_deg = 180 / 50; // 计算每个百分比所占的角度(3.6度/1%)
-
- if (percent) { // 判断传入的百分比是否存在(非0、非undefined、非null等)
- if (percent <= 50 && percent > 0) { // 如果百分比小于等于50且大于0
- console.log('小于50大于0');
- left_deg = 0; // 左边角度为0
- right_deg = percent * one_percent_deg; // 右边角度为百分比乘以每个百分比所占的角度
- } else if (percent > 50 && percent < 100) { // 如果百分比大于50且小于100
- console.log('50到100');
- left_deg = (percent - 50) * one_percent_deg - 180; // 左边角度为百分比减去50再乘以每个百分比所占的角度,再减去180度
- zIndex_left = 10; // 左边zIndex为10
- right_deg = 180; // 右边角度为180度
- } else if (percent === 100) { // 如果百分比等于100
- console.log('等于100');
- left_deg = 0; // 左边角度为0
- zIndex_left = 10; // 左边zIndex为10
- right_deg = 180; // 右边角度为180度
- }
- }
-
- // 返回一个对象,包含左边角度、右边角度和左边zIndex
- return {
- left_deg,
- right_deg,
- zIndex_left
- }
- }
-
特别注意一点,在 左侧半圆环,大于50%的时候,需要给左侧添加z-index=100,因为:其实他们左右的颜色大小都是不变的,只是在旋转,给我们视觉上的效果,就像是百分比一样。
我们给左侧限制了-180度的最小值,就是不让他旋转到右侧,而右侧0度的最小限制也是一个意思。
在大于50%的时候右侧为180度,我们看如果75%的时候,也是就左侧25%,且设置右侧小于180度会发生什么:

这里设置的左侧旋转-90度,右侧为80度,我们清晰的看到左侧的环形会来到右侧,中间会有缝隙,当然我们大于50%的时候,右侧会占满,同时使用z-index灵活去遮挡,就给我们视觉上看到正确的百分比,这里需要理解并实践。
注:代码参考自网络,有改变,仅做记录、参考使用