RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1069103
Accepted
Кевин
Кевин
Asked:2020-01-13 04:30:40 +0000 UTC2020-01-13 04:30:40 +0000 UTC 2020-01-13 04:30:40 +0000 UTC

如何制作圆形进度条并使用 CSS 对其进行动画处理

  • 772

有一个带框的圆圈:

一个圆圈

框架的长度需要逐渐减小(像进度条一样),但通常的border没有长度参数,只有宽度。

我认为一个标签可能适合这个<hr>,它的长度和宽度都可以减少,但我不知道如何使它弯曲。

不,当然这可以使用 SVG 或 来完成canvas,但我对 HTML、CSS 中的实现很感兴趣。

对此有什么想法吗?

html
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Best Answer
    user355286
    2020-01-13T04:49:20Z2020-01-13T04:49:20Z

    body {
      margin: 0;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .circle {
      width: 200px;
      height: 200px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
    }
    
    .circle>div {
      width: 100%;
      height: 100%;
      position: absolute;
      border-radius: 50%;
    }
    
    .outer {
      background-color: #03A9F4;
      clip-path: polygon(50% 0%, 100% 0, 100% 100%, 0 100%, 0 100%, 0 0, 50% 0, 50% 50%, 50% 50%);
    }
    
    .inner {
      transform: scale(0.95);
      background-color: #E0E0E0;
    }
    
    .circle:hover .outer {
      animation: xxx 2s linear forwards;
    }
    
    @keyframes xxx {
      12.5% {
        clip-path: polygon(50% 0%, 100% 0, 100% 100%, 0 100%, 0 100%, 0 0, 0 0, 50% 50%, 50% 50%);
      }
      25% {
        clip-path: polygon(50% 0%, 100% 0, 100% 100%, 0 100%, 0 100%, 0 50%, 0 50%, 50% 50%, 50% 50%);
      }
      37.5% {
        clip-path: polygon(50% 0%, 100% 0, 100% 100%, 0 100%, 0 100%, 0 100%, 0 100%, 50% 50%, 50% 50%);
      }
      50% {
        clip-path: polygon(50% 0%, 100% 0, 100% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 50%, 50% 50%);
      }
      62.5% {
        clip-path: polygon(50% 0%, 100% 0, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 50%, 50% 50%);
      }
      75% {
        clip-path: polygon(50% 0%, 100% 0, 100% 50%, 100% 50%, 100% 50%, 100% 50%, 100% 50%, 50% 50%, 50% 50%);
      }
      87.5% {
        clip-path: polygon(50% 0%, 100% 0, 100% 0, 100% 0, 100% 0, 100% 0, 100% 0, 50% 50%, 50% 50%);
      }
      100% {
        clip-path: polygon(50% 0%, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 50%, 50% 50%);
      }
    }
    <div class="circle">
      <div class="outer"></div>
      <div class="inner"></div>
    </div>

    你可以看到它是如何切割的:

    body {
      margin: 0;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    
    .circle {
      width: 200px;
      height: 200px;
      border-radius: 50%;
      
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
    }
    
    .circle > div {
      width: 100%;
      height: 100%;
      position: absolute;
    }
    .outer {
      background-color: #03A9F4;
      clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%, 0 0, 50% 0, 50% 50%);
    }
    
    .inner {
      transform: scale(0.95);
      background-color: #E0E0E0;
      opacity: 0.5;
    }
    
    .circle:hover .outer {
      animation: xxx 2s linear forwards;
    }
    
    @keyframes xxx {
      12.5% {
        clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%, 0 0, 0 0, 50% 50%);
      }
    
      25% {
        clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%, 0 50%, 0 50%, 50% 50%);
      }
      
      37.5% {
        clip-path: polygon(50% 0, 100% 0, 100% 100%, 0 100%, 0 100%, 0 100%, 50% 50%);
      }
      
      50% {
        clip-path: polygon(50% 0, 100% 0, 100% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 50%);
      }
      
      62.5% {
        clip-path: polygon(50% 0, 100% 0, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 50%);
      }
      
      75% {
        clip-path: polygon(50% 0, 100% 0, 100% 50%, 100% 50%, 100% 50%, 100% 50%, 50% 50%);
      }
      
      87.5% {
        clip-path: polygon(50% 0, 100% 0, 100% 0, 100% 0, 100% 0, 100% 0, 50% 50%);
      }
      
      100% {
        clip-path: polygon(50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 0, 50% 50%);
      }
    }
    <div class="circle">
      <div class="outer"></div>
      <div class="inner"></div>
    </div>

    • 9
  2. Alexandr_TT
    2020-01-13T18:06:22Z2020-01-13T18:06:22Z

    但是为什么需要一个纯 CSS 的解决方案呢?
    SVG 正是为实现图形而存在,完美支持 CSS 的所有规则。

    另一方面,这个 CSS 不能做 SVG 能做的所有事情。

    如果使用 SVG 有困难,那么您可以在矢量编辑器中创建一个 SVG 图形,只需单击几下,复制path它,然后将所有动画传输到 CSS。

    在此处输入图像描述

    明星的动画示例,见话题底部。

    比较代码变得更短和更清晰的程度。
    标记在任何地方都是相同的,您只需要准确知道形状的 svg 轮廓的全长并设置适当的参数stroke-dasharray stroke-dashoffset

    第一行擦除示例

    通过stroke-dashoffset从零增加到最大值来实现628px

    灰色方块显示 SVG 画布的边框,蓝色矩形是 SVG 的容器。

    .circle {
    position:relative;
    width:215px;
    height:250px;
    background:#CDE9FF;
    }
    .svg1 {
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    }
    #circ {
    fill:#E0E0E0;
    stroke:#03A9F4;
    stroke-width:6;
    stroke-dasharray:628;
    stroke-dashoffset:0;
    }
    #circ:hover {
    animation: progress 2s linear forwards;
    }
    
    @keyframes progress {
    100% {stroke-dashoffset:628;}
    }
    <div class="circle">
    
    <svg class="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
      width="210" height="210" viewBox="0 0 210 210" style="border:1px solid gray" >  
    
    <circle  id="circ" transform="rotate(-90 105 105)" cx="105" cy="105" r="100" />
    </svg>
    
    </div>

    第二个例子stroke-dasharray

    .circle {
    position:relative;
    width:215px;
    height:250px;
    background:#CDE9FF;
    }
    .svg1 {
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    }
    #circ {
    fill:#E0E0E0;
    stroke:purple;
    stroke-width:6;
    stroke-dasharray:628,0;
    stroke-dashoffset:-628;
    }
    #circ:hover {
    animation: progress 2s linear forwards;
    }
    
    @keyframes progress {
    100% {stroke-dasharray:0,628;}
    }
    <div class="circle">
    
    <svg class="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
      width="210" height="210" viewBox="0 0 210 210" style="border:1px solid gray" >  
    
    <circle  id="circ" transform="rotate(-90 105 105)" cx="105" cy="105" r="100" />
    </svg>
    
    </div>

    第三个例子是两行擦除的动画

    仅更改属性stroke-dasharray

    .circle {
    position:relative;
    width:215px;
    height:250px;
    background:#CDE9FF;
    }
    .svg1 {
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    }
    #circ {
    fill:#E0E0E0;
    stroke:purple;
    stroke-width:6;
    stroke-dasharray:314,0 314,0;
    stroke-dashoffset:-157;
    }
    #circ:hover {
    animation: progress 2s linear forwards;
    }
    
    @keyframes progress {
    100% {stroke-dasharray:0,314 0,314;}
    }
    <div class="circle">
    <svg class="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
      width="210" height="210" viewBox="0 0 210 210" style="border:1px solid gray" >  
    <circle  id="circ" transform="rotate(-90 105 105)" cx="105" cy="105" r="100" />
    </svg>
    
    </div>

    反之亦然,从一个点用两条线绘制

    为此,您只需要交换参数stroke-dasharray

    .circle {
    position:relative;
    width:215px;
    height:250px;
    background:#CDE9FF;
    }
    .svg1 {
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    }
    #circ {
    fill:#E0E0E0;
    stroke:purple;
    stroke-width:6;
    stroke-dasharray:0,314 0,314;
    stroke-dashoffset:314;
    }
    #circ:hover {
    animation: progress 2s linear forwards;
    }
    
    @keyframes progress {
    100% {stroke-dasharray:0,0 628,0;}
    }
    <div class="circle">
    <svg class="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
      width="210" height="210" viewBox="0 0 210 210" style="border:1px solid gray" >  
    <circle  id="circ" transform="rotate(-90 105 105)" cx="105" cy="105" r="100" />
    </svg>
    
    </div>

    从单个点绘制六边形边的动画

    .circle {
    position:relative;
    width:215px;
    height:250px;
    background:#CDE9FF;
    }
    .svg1 {
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    }
    #hex {
    fill:#E0E0E0;
    stroke:purple;
    stroke-width:6;
    stroke-dasharray:0,300 0,300;
    stroke-dashoffset:300;
    }
    #hex:hover {
    animation: progress 2s linear forwards;
    }
    
    @keyframes progress {
    100% {stroke-dasharray:0,0 600,0;}
    }
    <div class="circle">
    <svg class="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
      width="210" height="210" viewBox="0 0 210 210" style="border:1px solid gray" >  
    <path id="hex" d="m105 5 86.6 50 0 100L105 205 18.4 155l0-100z"/>
    </svg>
    </div>

    星光动画

    .circle {
    position:relative;
    width:215px;
    height:250px;
    background:#CDE9FF;
    }
    .svg1 {
    position:absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    }
    #star {
    fill:#E0E0E0;
    stroke:purple;
    stroke-width:6;
    stroke-dasharray:0,332 0,332;
    stroke-dashoffset:332;
    }
    #star:hover {
    animation: progress 2s linear forwards;
    }
    
    @keyframes progress {
    100% {stroke-dasharray:0,0 664,0;}
    }
    <div class="circle">
    <svg class="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
      width="210" height="210" viewBox="0 0 210 210" style="border:1px solid gray" >  
    <path id="star" d="m105 5 29.4 59.5 65.7 9.5-47.6 46.4 11.2 65.5L105 155 46.2 185.9 57.4 120.5 9.9 74.1 75.6 64.5Z"/>
    </svg>
    </div>

    • 5
  3. Сергей Мишин
    2020-01-13T17:16:07Z2020-01-13T17:16:07Z

    .progress-bar-wrapper {
      position: relative;
      display: block;
      height: 100px;
    }
    
    .center-circle {
      width: 60px;
      height: 60px;
      position: absolute;
      border-radius: 50%;
      background: grey;
      transform: translate3d(15px, 15px, 0);
      z-index: 3;
    }
    
    .sector {
      width: 72px;
      height: 72px;
      position: absolute;
      border-radius: 50%;
      transform: translate3d(7px, 7px, 0);
      z-index: 2;
      display: block;
      background-color: green;
      border: 2px solid green;
      background-image: linear-gradient(108deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%);
      animation: background 2s infinite;
    }
    
    @keyframes background {
      15% {
        background-image: linear-gradient(126deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%);
      }
      25% {
        background-image: linear-gradient(180deg, transparent 50%, white 50%), linear-gradient(90deg, white 50%, transparent 50%);
      }
      50% {
        background-image: linear-gradient(90deg, white 50%, transparent 50%);
      }
      75% {
        background-image: linear-gradient(180deg, transparent 50%, green 50%), linear-gradient(90deg, white 50%, transparent 50%);
      }
      100% {
        background-image: none;
      }
    }
    <div class="progress-bar-wrapper">
      <div class="center-circle"></div>
      <div class="sector"></div>
    </div>

     /* 10% = 126deg = 90 + ( 360 * .1 ) */
    

    如果要将值更改 1,则必须 background-image: linear-gradient在每帧中将值从 90 更改为 450。

    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何从列表中打印最大元素(str 类型)的长度?

    • 2 个回答
  • Marko Smith

    如何在 PyQT5 中清除 QFrame 的内容

    • 1 个回答
  • Marko Smith

    如何将具有特定字符的字符串拆分为两个不同的列表?

    • 2 个回答
  • Marko Smith

    导航栏活动元素

    • 1 个回答
  • Marko Smith

    是否可以将文本放入数组中?[关闭]

    • 1 个回答
  • Marko Smith

    如何一次用多个分隔符拆分字符串?

    • 1 个回答
  • Marko Smith

    如何通过 ClassPath 创建 InputStream?

    • 2 个回答
  • Marko Smith

    在一个查询中连接多个表

    • 1 个回答
  • Marko Smith

    对列表列表中的所有值求和

    • 3 个回答
  • Marko Smith

    如何对齐 string.Format 中的列?

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5