【问题标题】:Progress Circle Completion进度圈完成
【发布时间】:2020-12-24 04:02:00
【问题描述】:

我正在尝试创建一个基于百分比完成圆圈的方程式或方法。

这是我所拥有的:

我希望能够完成基于百分比增加的圆圈,并让它从侧面开始,如下图所示:

我试图让对齐方式相似,但我没有运气或计算。

这是我的代码:

#progress-bar {
  position: absolute;
  left: 50%;
  top: 55%;
  transform: translate(-51%, -50%);
  width: 40%;
}

.container {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: space-around;
}

.container .card {
  position: relative;
  width: 400px;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400px;
  border-radius: 4px;
  text-align: center;
  overflow: hidden;
  transition: 0.5s;
}

.container .card:before {
  content: '';
  position: absolute;
  top: 0;
  left: -50%;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.03);
  pointer-events: none;
  z-index: 1;
}

.percent {
  position: relative;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  box-shadow: inset 0 0 50px #000;
  background: #222;
  z-index: 1000;
}

.percent .number {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
}

.percent .number h2 {
  color: #777;
  font-weight: 700;
  font-size: 40px;
  transition: 0.5s;
}

.card:hover .percent .number h2 {
  color: #fff;
  font-size: 60px;
}

.percent .number h2 span {
  font-size: 24px;
  color: #777;
  transition: 0.5s;
}

.card:hover .percent .number h2 span {
  color: #fff;
}

.text {
  position: relative;
  color: #777;
  margin-top: 40px;
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 1px;
  text-transform: uppercase;
  transition: 0.5s;
}

svg {
  position: relative;
  width: 123%;
  height: 123%;
  z-index: 1000;
}

svg circle {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: #191919;
  stroke-width: 10;
  stroke-linecap: round;
  transform: translate(-28px, -28px);
}

svg circle:nth-child(2) {
  stroke-dasharray: 440;
  stroke-dashoffset: calc( 440 - (440 * 90) / 100);
  stroke: #00ff43;
}
<div class="container">
  <div class="card">
    <div class="box">
      <div class="percent">
        <svg>
                      <!-- <circle cx="70" cy="70" r="70"></circle>
                      <circle cx="70" cy="70" r="70"></circle> -->

                      <circle cx="50%" cy="50%" r="40%"></circle>
                      <circle cx="50%" cy="50%" r="40%"></circle>
                    </svg>
        <div class="number">
          <h2>60<span>%</span></h2>
        </div>
      </div>
      <h2 class="text">69 of 115 Goals Completed</h2>
    </div>
  </div>
</div>

【问题讨论】:

    标签: css geometry progress calculation


    【解决方案1】:

    在第二个圆上设置虚线长度和对齐都有问题。

    看起来好像原始代码使用第一个圆圈来填充第二个圆圈,但它已被圆形 div 百分比变得多余。 对齐已关闭,因为圆在直径为 123% 的 svg 内的半径为 40%,这使它与此圆形 div 不同。 已尝试通过平移 -23px 重新对齐 简化我们只画一个 svg 圆圈,它有绿色百分比的边框,并确保它正好超过 div 百分比

    现在我们来计算将显示 % 的绿色条 CSS 有一个 calc,看起来像是在尝试计算 90% 分数的破折号大小。 但它看起来不像合法的 CSS(需要为要执行的每个计算进行计算)。 并且 CSS 也有一个固定的 440,它大致代表 60% 而不是整个圆圈。 在这两个设置上从头开始,我们需要破折号是圆的圆周的 n%。 所以我们先计算圆的周长,然后计算它的这个百分比,然后画出这个长度,间隔为 cicumference - 长度。

    注意 - 因为您可以在带有边框或阴影的曲线上获得边缘效果,所以黑色圆圈的背景已更改为半径稍小的径向渐变图像。

    这个 sn-p 有一个额外的输入元素,您可以在其中输入达到的目标数量,以检查绿色弧线的长度是否正确。

    document.querySelector('.goals').addEventListener('change', function(){
        var goals = parseInt(this.value);
        var circle = document.querySelector('circle');
        var percentdiv = document.querySelector('.percent');
        var completed = document.querySelector('.completed');
        completed.innerHTML = goals;
        var totaldiv = document.querySelector('.total');
        var total = totaldiv.innerHTML;
        var pc = goals*100/total;
        var r = circle.getAttribute('r').replace('%','')*percentdiv.clientWidth/100;//actual radius of the circle
        var c = Math.PI*(r*2);//circumference is 2*pi*r
        
        if (isNaN(goals)) { pc = 100; }
        else if (pc < 0) { pc = 0;}
        else if (pc > 100) { pc = 100;}
        document.querySelector('.number h2').innerHTML = Math.floor(pc) + '<span>%</span>';
    
        var length = pc * c/100;
            
        circle.style.strokeDasharray = length + ' ' + (c-length);
        circle.style.strokeWidth = (length > 0) ? '5%': 0;
    });
        * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
        }
            #progress-bar {
      position: absolute;
      left: 50%;
      top: 55%;
      transform: translate(-51%, -50%);
      width: 40%;
    }
    
    .container {
      position: relative;
      width: 100%;
      display: flex;
      justify-content: space-around;
    }
    
    .container .card {
      position: relative;
      width: 400px;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 400px;
      border-radius: 4px;
      text-align: center;
      overflow: hidden;
      transition: 0.5s;
    }
    
    .container .card:before {
      content: '';
      position: absolute;
      top: 0;
      left: -50%;
      width: 100%;
      height: 100%;
      background: rgba(255, 255, 255, 0.03);
      pointer-events: none;
      z-index: 1;
    }
    
    .percent {
      position: relative;
      width: 300px;
      height: 300px;
      border-radius: 50%;
      border-color: transparent;
      border-width: 0;
      border-style: none;
      rbox-shadow: inset 0 0 50px #000;
      background-image: radial-gradient(#444 0%, #222 70%, transparent 70%, transparent 100%);
      rbackground: #222;
      z-index: 1000;
    }
    
    .percent .number {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 50%;
    }
    
    .percent .number h2 {
      color: #777;
      font-weight: 700;
      font-size: 40px;
      transition: 0.5s;
    }
    
    .card:hover .percent .number h2 {
      color: #fff;
      font-size: 60px;
    }
    
    .percent .number h2 span {
      font-size: 24px;
      color: #777;
      transition: 0.5s;
    }
    
    .card:hover .percent .number h2 span {
      color: #fff;
    }
    
    .text {
      position: relative;
      color: #777;
      margin-top: 40px;
      font-weight: 700;
      font-size: 18px;
      letter-spacing: 1px;
      text-transform: uppercase;
      transition: 0.5s;
    }
    
    svg {
      width: 100%;
      height: 100%;
      z-index: 1000;
    }
    
    svg circle {
      fill: none;
      stroke-width: 0;
      stroke-linecap: round;
      stroke: #00ff43;
    }
    <div class="container">
      <div class="card">
        <div class="box">
          <div class="percent">
                          <svg>
                          <circle cx="50%" cy="50%" r="47.5%"></circle>
                        </svg>
            <div class="number">
              <h2>0<span>%</span></h2>
            </div>
          </div>
          <h2 class="text"><span class="completed">0</span> of <span class="total">115</span> Goals Completed</h2>
        </div>
      </div>
    </div>
    Goals completed: <input class="goals" type='number'/>

    【讨论】:

    • 非常感谢!有没有办法删除“目标已完成:”,以便我可以通过更改代码中“目标”的静态值来更新进度?我希望能够从外部来源获取信息。我不希望出现“目标已完成”的提示或用户必须更新的区域。
    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    相关资源
    最近更新 更多