【问题标题】:Is it possible to draw a partial circle outline in CSS (open ring shape)?是否可以在 CSS 中绘制部分圆形轮廓(开环形状)?
【发布时间】:2017-07-03 06:09:28
【问题描述】:

我对完全在 CSS 中创建加载微调器很感兴趣,但为了做到这一点,我需要能够像这样绘制一个开放的环形:

圆环会绕着圆的圆周画自己。这在 CSS 中可以实现吗?

【问题讨论】:

  • 您可以使用 stroke-dasharray 设置 SVG 圆形样式。它是动画的,既可以在 CSS 中使用,也可以作为属性使用:developer.mozilla.org/en-US/docs/Web/SVG/Attribute/…
  • @JakubJagieło 这可以让我沿着圆的圆周绘制边框吗?
  • 诀窍在于,您基本上将围绕圆周的边框设置为仅用一个短划线的虚线,并通过为该短划线长度设置动画,您可以创建线条在周围生长的效果。
  • @colindunn 我已经使用 SVG 和stroke-dasharray 更新了我的答案,使其工作方式有些相似。这可能是仅使用 HTML 和 CSS 来“绘制”圆圈轮廓的唯一方法。

标签: css css-animations css-shapes


【解决方案1】:

要创建一个逐渐绘制其外部路径的圆,请使用 SVG。

SVG 的stroke-dasharray 属性会将任何路径转换为虚线,您可以通过将虚线大小设置为几乎与路径本身一样长来利用它。

然后使用 CSS 动画逐渐更改 stroke-dashoffset 以围绕圆圈的周边移动破折号。

circle {
  fill: white;
  stroke: black;
  stroke-width: 2;
  stroke-dasharray: 250;
  stroke-dashoffset: 1000;
  animation: rotate 5s linear infinite;
}

@keyframes rotate {
  to {
    stroke-dashoffset: 0;
  }
}
<svg height="100" width="100">
  <circle cx="50" cy="50" r="40" />
</svg>

【讨论】:

    【解决方案2】:

    静态图片

    仅依赖于单个 HTML 元素和 CSS 类的简化示例可能如下所示:

    .arc {
      /* Border size and color */
      border: 2px solid #000;
      /* Creates a circle */
      border-radius: 50%;
      /* Circle size */
      height: 100px;
      width: 100px;
      /* Use transparent borders to define opening (more transparent = larger opening) */
      border-top-color: transparent;
      border-left-color: transparent;
      /* Use transform to rotate to adjust where opening appears */
      transform: rotate(300deg)
    }
    

    示例

    .arc {
      border: 2px solid #000;
      border-radius: 50%;
      height: 100px;
      width: 100px;
      border-top-color: transparent;
      transform: rotate(300deg)
    }
    &lt;div class='arc'&gt;&lt;/div&gt;

    旋转图像

    您可以通过使用@keyframes 来利用基于 CSS 的动画,对前面的静态示例应用基本旋转:

    .arc {
      /* Border size and color */
      border: 2px solid #000;
      /* Creates a circle */
      border-radius: 50%;
      /* Circle size */
      height: 100px;
      width: 100px;
      /* Use transparent borders to define opening (more transparent = larger opening) */
      border-top-color: transparent;
      /* Rotate indefinitely (longer time = slower rotation) */
      animation: rotate 2s infinite linear;
    }
    
    @keyframes rotate {
      0%    { transform: rotate(0deg);  }
      100%  { transform: rotate(360deg);  }
    }
    

    示例

    .arc {
      border: 2px solid #000;
      border-radius: 50%;
      height: 100px;
      width: 100px;
      border-top-color: transparent;
      animation: rotate 2s infinite linear;
    }
    
    @keyframes rotate {
      0%    { transform: rotate(0deg);  }
      100%  { transform: rotate(360deg);  }
    }
    &lt;div class='arc'&gt;&lt;/div&gt;

    绘图(无 SVG)

    另一种方法that I came across,虽然不像以前的方法那样优雅,但似乎可以达到您想要的效果。 In 涉及使用多个动画以及根据需要显示/隐藏圆圈的不同部分。

    代码 sn-p 包含一个演示它的示例。

    示例

    #container {
      position: absolute;
      width: 100px;
      height: 100px;
      animation: colors 1s infinite;
    }
    #halfclip {
      width: 50%;
      height: 100%;
      right: 0px;
      position: absolute;
      overflow: hidden;
      transform-origin: left center;
      animation: cliprotate 4s steps(2) infinite;
      -webkit-animation: cliprotate 4s steps(2) infinite;
    }
    .halfcircle {
      box-sizing: border-box;
      height: 100%;
      right: 0px;
      position: absolute;
      border: solid 2px transparent;
      border-top-color: #000;
      border-left-color: #000;
      border-radius: 50%;
    }
    #clipped {
      width: 200%;
      animation: rotate 2s linear infinite;
      -webkit-animation: rotate 2s linear infinite;
    }
    #fixed {
      width: 100%;
      transform: rotate(135deg);
      animation: showfixed 4s steps(2) infinite;
      -webkit-animation: showfixed 4s linear infinite;
    }
    @-webkit-keyframes cliprotate {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(360deg);
      }
    }
    @keyframes cliprotate {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(360deg);
      }
    }
    @-webkit-keyframes rotate {
      0% {
        transform: rotate(-45deg);
      }
      100% {
        transform: rotate(135deg);
      }
    }
    @keyframes rotate {
      0% {
        transform: rotate(-45deg);
      }
      100% {
        transform: rotate(135deg);
      }
    }
    @-webkit-keyframes showfixed {
      0% {
        opacity: 0;
      }
      49.9% {
        opacity: 0;
      }
      50% {
        opacity: 1;
      }
      100% {
        opacity: 1;
      }
    }
    <div id="container">
      <div id="halfclip">
        <div class="halfcircle" id="clipped">
        </div>
      </div>
      <div class="halfcircle" id="fixed">
      </div>
    </div>

    绘图(使用 SVG)

    利用 SVG 可能是解决此问题的最佳方法,因为它明确设计用于处理浏览器中的绘图。如果 SVG 支持可用,我强烈推荐这种方法。

    Dylan's response 详细说明了这个实现的样子。

    【讨论】:

    • 这给了我一个 3/4 整圆的静态表示,但它不允许我沿着圆周平滑地绘制轮廓。
    • 啊,我似乎误解了您要查找的内容。您可以为使用关键帧提供的相同示例制作动画(即让给定的图标无限旋转)。你想让圆圈基本上出现一个点,画圆圈然后重新开始吗?
    • @RionWilliams 哇,没有 SVG 的绘图方法真是太疯狂了!我不会认为这是可能的,无论是谁想出来的都是绝妙的主意。
    • 是的,它很狂野:)
    【解决方案3】:

    您可以只使用一个伪元素::after 来创建开放部分,只需与圆形元素重叠。优点是,开放的部分可以任意长(不限于 3/4 整圈)。

    .circle {
      width: 100px;
      height: 100px;
      border: 2px solid;
      border-radius: 50%;
      margin: 30px;
      animation: rotate 1s infinite linear;
    }
    .circle::after {
      content: "";
      display: block;
      width: 80px;
      height: 80px;
      background: white;
      border-radius: 50%;
      margin: -30% 0 0 -30%;
    }
    @keyframes rotate {
      0%    { transform: rotate(0deg);  }
      100%  { transform: rotate(360deg);  }
    }
    &lt;div class="circle"&gt;&lt;/div&gt;

    【讨论】:

      【解决方案4】:

      伪版也可以使用linear-gradient(阴影可减可加)和background-clip

      它在哪里可用,mix-blend-mode 可以让它透明,

      currentcoloranimation 也可用于动画颜色:

      .loader {
        font-size: 1.5em;
        color: gray;
        position: relative;
        padding: 3px;
        /* make a square */
        height: 100px;
        width: 100px;
        /* center content*/
        display: flex;
        align-items: center;
        justify-content: center;
        animation: coloranim infinite 5s;
      }
      
      .circle {
        border-radius: 100%;
        overflow: hidden;
      }
      
      .loader:after {
        border-radius: inherit;
        color: inherit;
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: 0;
        right: 0;
        padding: 3px;
        background: linear-gradient(white, white), linear-gradient(0deg, transparent 40%, currentcolor 60%), linear-gradient(50deg, transparent 50%, currentcolor 52%);
        background-clip: content-box, border-box, border-box;
        z-index: -1;
        mix-blend-mode: multiply;/* if avalaible, else bg remains white */
      }
      
      .spin:after {
        animation: spin 2s linear infinite;
      }
      
      @keyframes spin {
        to {
          transform: rotate(360deg);
        }
      }
      
      @keyframes coloranim {
        20% {
          color: tomato;
        }
        40% {
          color: purple;
        }
        60% {
          color: turquoise;
        }
        80% {
          color: green;
        }
      }
      
      
      /* demo purpose, use your own style wherever your loader is needed */
      
      html {
        height: 100%;
        display: flex;
        background: url(http://lorempixel.com/800/800/food/3);
        background-size: cover;
        box-shadow: inset 0 0 0 2000px rgba(255, 255, 255, 0.3)
      }
      
      body {
        margin: auto;
      }
      &lt;div class="spin circle loader coloranim"&gt; loading... &lt;/div&gt;

      http://codepen.io/gc-nomade/pen/YNbmGE

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-06
        相关资源
        最近更新 更多