css+html<半圆形进度条>

1,298 阅读3分钟

一般很多插件都自带的有进度条的组件,但是半圆形的却很少。

这个时候就要考虑如何实现下面这种扇形效果,很多人会考虑采用 canvas实现半圆形进度,但是这种方式在微信小程序或其它方面的兼容性和效果都不是很好,所以这里教大家如何通过css+html的方式实现这种效果。

如何生成一个半圆

image.png

这里是通过 conic-gradient角向渐变 生成的半圆,当然你也可以通过其它方式生成,这里主要是通过旋转角度实现进度展示效果的(如果直接通过conic-gradient不会有后面的渐变效果,所以大家可以选择使用,不理解的可以继续往下看)

<div class="semicircle-box">
 <div class="semicircle-plan"> </div>
</div>
.semicircle-box {
   width: 400px;
  height: 400px;
  position: relative;
  margin-bottom: 20px;
}
.semicircle-plan {
  width: 400px;
  height: 400px;
  background: conic-gradient(#3481FD 0, #3481FD 50%, #f8f8f8 50%, #f8f8f8 100%);
  transform: rotate(90deg);
  border-radius: 50%;
}

如何生成一个圆环

image.png

直接生成一个白色的遮罩层,放在中心位置,遮挡住即可

<div class="semicircle-box">
<div class="semicircle-plan"> </div>
<!-- 中间白色遮挡层 -->
<div class="cover"> </div>
</div>
...
.cover {
  position: absolute;
  width: 100%;
  height: 100%;
  background-color: white;
  transform: scale(0.8);
  border-radius: 50%;
  z-index: 5;
  top: 0;
}

如何实现半圆进度

image.png

此时再包裹一个.semicircle-box-hidden是宽400,高200其它超出隐藏掉,就实现一个半圆了。

  • 通过控制.semicircle-plan的旋转控制进度,默认旋转90deg,所以旋转角度为value*1.8deg + 90deg(1.8(1度 = 1.8角度) = 180(角度)/100(进度))
<div class="semicircle-box">
  <div class="semicircle-box-hidden" style="width: 400px;height: 200px;">
    <!-- 圆环进度 -->
    <div class="semicircle-plan"> </div>
    <!-- 中间白色遮挡层 -->
    <div class="cover"> </div>
  </div>
</div>
...
.semicircle-plan {
  width: 400px;
  height: 400px;
  background: conic-gradient(#3481FD 0, #3481FD 50%, #f8f8f8 50%, #f8f8f8 100%);
 /* 动态修改圆环旋转度数,默认会有90deg */
  transform: rotate(calc(var(--value) * 1.8deg + 90deg));
  border-radius: 50%;
}
.semicircle-box-hidden{
  width: 400px;
  height: 200px;
  overflow: hidden;
}
.cover {
  position: absolute;
  width: 100%;
  height: 200%; //因为高度变成了 200 所以遮罩层的高度要随之扩大一半
  background-color: white;
  transform: scale(0.8);
  border-radius: 50%;
  z-index: 5;
  top: 0;
}

如何添加小圆点

image.png

很显然只实现上面的效果是远远不够的,下面通过追加几个小圆点使我们的进度条更好看些。

主要还是通过定位和旋转角度实现小圆点的跟随效果。

  • .dot旋转角度transform: rotate(calc(var(--value)*1.8deg))
  • .dot的旋转圆心为 transform-origin: 500% 50%;,因为这里是通过百分比控制小圆点,所以通过百分比换算x轴偏移位置比较方便

image.png

  • .semicircle-box::before,::after添加两头多出来的小半圆
<div class="semicircle-box" style="width: 400px;height: 200px;">
  <div class="dot"> </div>
  <div class="semicircle-box-hidden">
    <!-- 圆环进度 -->
    <div class="semicircle-plan"> </div>
    <!-- 中间白色遮挡层 -->
    <div class="cover"> </div>
  </div>
</div>
...
.dot {
  /* 动态改变小圆点旋转方向 */
  transform: rotate(18deg);
  position: absolute;
  width: 10%;
  height: 20%;
  border-radius: 50%;
  left: 0;
  top: 90%;
  z-index: 10;
  background-color: #3481FD;
  border: 10px solid white;
  box-sizing: border-box;
  transform-origin: 500% 50%;
  box-shadow: 0 0 0 4px white, 0 0 10px #cccccc;
  transition: transform 0.5s;
}
.semicircle-box::before,
.semicircle-box::after {
  content: "";
  position: absolute;
  top: 90%;
  width: 10%;
  height: 20%;
  border-radius: 50%;
  background: #f8f8f8;
  z-index: 1;
}

.semicircle-box::before {
  background-color: #3481FD;
}

.semicircle-box::after {
  left: 90%;
  z-index: -1;
}