html - SVG 动画最后没有正确关闭(小间隙仍然存在)

标签 html css svg

我对 SVG 比较陌生。尝试实现六边形加载器,90% 已经完成,但在动画结束时六边形没有完全闭合(仍然存在一个小间隙)。实际上,我使用 Adob​​e Illustrator 获取路径坐标。

链接:jsfiddle.net/srigar/fhmbqtg7/1/

最佳答案

您可以采用多种方法。如果您不介意圆 Angular 联接,则可以采用@demonofthemists 的方法。

但在我演示其他方法之前,我将清理您的路径。它使用 15 个路径命令来制作六边形。您应该只需要 6 个。它的末尾还有一个杂散的“-0”,什么都不做。我还清理了 CSS。最后,您的路径长度仅为 245.68,因此 300 的破折号数组太长,因此您看不到 ease-in-out 动画计时的效果。

这是清理后的样本。

.loader path {
  stroke-width: 10;
  fill: none;
}

.loader #fill {
  stroke:#4C83C4;
  stroke-dasharray: 246;
  animation: dash 5s ease-in-out infinite;
}
.loader #border {
  stroke:#d6d5d5;
}
.loader svg {
  width: 600px;
  height: 300px;
  display: block;
  margin: 0 auto;
  margin-bottom: 40px;
  opacity: 0.5;
  position: relative;
}

@keyframes dash {
  0% {
    stroke-dashoffset: 246;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
<div class="loader">
  <svg viewBox="0 -10 97.59 119.306">
    <g>
      <path id="border"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"/>
      <path id="fill"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"/>
    </g>
  </svg>
</div>

<label>Author: SRIGAR</label>

好的,解决方案。

<强>1。 “方形”线帽和 mask

您可以切换到方形线帽而不是圆形,但这会导致线帽延伸到六边形之外。您可以使用 mask 来解决这个问题。

.loader path {
  stroke-width: 10;
  fill: none;
}

.loader #fill {
  stroke:#4C83C4;
  stroke-dasharray: 246;
  stroke-linecap: square;
  animation: dash 5s ease-in-out infinite;
  mask: url(#loader-mask);
}
.loader #border {
  stroke:#d6d5d5;
}
.loader svg {
  width: 600px;
  height: 300px;
  display: block;
  margin: 0 auto;
  margin-bottom: 40px;
  opacity: 0.5;
  position: relative;
}

@keyframes dash {
  0% {
    stroke-dashoffset: 246;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
<div class="loader">
  <svg viewBox="0 -10 97.59 119.306">
    <defs>
      <mask id="loader-mask">
        <rect width="100%" height="100%" fill="black"/>
        <path d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"
              stroke="white"/>
      </mask>
    </defs>
    <g>
      <path id="border"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"/>
      <path id="fill"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"/>
    </g>
  </svg>
</div>

<label>Author: SRIGAR</label>

不幸的是,这在路径的开头看起来不太好。

<强>2。扩展路径的结尾,带掩码

另一种方法是避开线帽,而只是将路径的终点延伸到起点之后一点。当然,这会使行变长,因此您还需要使破折号数组的值变大。而且我们仍然需要使用 mask ,这样我们就只能看到我们想要保留的延伸部分。

.loader path {
  stroke-width: 10;
  fill: none;
}

.loader #fill {
  stroke:#4C83C4;
  stroke-dasharray: 250;
  animation: dash 5s ease-in-out infinite;
  mask: url(#loader-mask);
}
.loader #border {
  stroke:#d6d5d5;
}
.loader svg {
  width: 600px;
  height: 300px;
  display: block;
  margin: 0 auto;
  margin-bottom: 40px;
  opacity: 0.5;
  position: relative;
}

@keyframes dash {
  0% {
    stroke-dashoffset: 250;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
<div class="loader">
  <svg viewBox="0 -10 97.59 119.306">
    <defs>
      <mask id="loader-mask">
        <rect width="100%" height="100%" fill="black"/>
        <path d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"
              stroke="white"/>
      </mask>
    </defs>
    <g>
      <path id="border"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"/>
      <path id="fill"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 l-38.8,-22.6"/>
    </g>
  </svg>
</div>

<label>Author: SRIGAR</label>

因此,有一些技巧可以帮助您入门。如果你愿意,你可以变得更漂亮——例如,如果你想要一个垂直的开始/结束连接,那么你可以使用几个蒙版并将动画分成两部分来做到这一点。但我现在会让事情变得简单,以避免让这个答案过于困惑。

更新

<强>3。更简洁的开始和结束

.loader path {
  stroke-width: 10;
  fill: none;
}

.loader #fill-left,
.loader #fill-right {
  stroke:#4C83C4;
  animation: dash 5s ease-in-out infinite;
}

.loader #fill-left {
  stroke-dasharray: 254;
  mask: url(#left-mask);
}

.loader #fill-right {
  stroke-dasharray: 168 254;
  mask: url(#right-mask);
}

.loader #border {
  stroke:#d6d5d5;
}
.loader svg {
  width: 600px;
  height: 300px;
  display: block;
  margin: 0 auto;
  margin-bottom: 40px;
  opacity: 0.5;
  position: relative;
}

@keyframes dash {
  0% {
    stroke-dashoffset: 254;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
<div class="loader">
  <svg viewBox="0 -10 97.59 119.306">
    <defs>
      <mask id="left-mask">
        <rect width="100%" height="100%" fill="black"/>
        <path d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"
              stroke="white"/>
        <rect x="43.3" width="100%" height="100%" fill="black"/>
      </mask>
      <mask id="right-mask">
        <rect width="100%" height="100%" fill="black"/>
        <path d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"
              stroke="white"/>
        <rect width="43.3" height="100%" fill="black"/>
      </mask>
    </defs>
    <g>
      <path id="border"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"/>
      <path id="fill-left"
            d="M46.8,6 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 l-38.8,-22.6"/>
      <path id="fill-right"
            d="M8,69.8 L43.3,90.3 L78.6,69.8 V28.6 l-38.8,-22.6"/>
    </g>
  </svg>
</div>

<label>Author: SRIGAR</label>

它是如何工作的。

如上所述,为了得到更整洁的开始和结束,我们必须将掩码分成两半。一个是左半部分,这样我们就可以延长起点线(就像我们对终点线所做的那样)并使起点垂直。第二个是我们可以像之前那样延长终点线。

为清楚起见,这是左侧蒙版的样子。

.loader path {
  stroke-width: 10;
  fill: none;
}

.loader svg {
  width: 600px;
  height: 300px;
}
<div class="loader">
  <svg viewBox="0 -10 97.59 119.306">
    <rect width="100%" height="100%" fill="black"/>
    <path d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"
          stroke="white"/>
    <rect x="43.3" width="100%" height="100%" fill="black"/>
  </svg>
</div>

这是正确的面具。

.loader path {
  stroke-width: 10;
  fill: none;
}

.loader svg {
  width: 600px;
  height: 300px;
}
<div class="loader">
  <svg viewBox="0 -10 97.59 119.306">
    <rect width="100%" height="100%" fill="black"/>
    <path d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"
          stroke="white"/>
    <rect width="43.3" height="100%" fill="black"/>
  </svg>
</div>

如果我们移除 mask 并将填充线设为半透明,您可以看到它们是如何排列以与 mask 配合使用的。

.loader path {
  stroke-width: 10;
  fill: none;
  stroke-opacity: 0.5;
}

.loader #fill-left,
.loader #fill-right {
  stroke:#4C83C4;
  animation: dash 5s ease-in-out infinite;
}

.loader #fill-left {
  stroke-dasharray: 254;
}

.loader #fill-right {
  stroke: red;
  stroke-dasharray: 168 254;
}

.loader #border {
  stroke:#d6d5d5;
}
.loader svg {
  width: 600px;
  height: 300px;
  display: block;
  margin: 0 auto;
  margin-bottom: 40px;
  opacity: 0.5;
  position: relative;
}

@keyframes dash {
  0% {
    stroke-dashoffset: 254;
  }
  100% {
    stroke-dashoffset: 0;
  }
}
<div class="loader">
  <svg viewBox="0 -10 97.59 119.306">
    <g>
      <path id="border"
            d="M43.3,8.1 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 z"/>
      <path id="fill-left"
            d="M46.8,6 L8,28.6 v41.2 L43.3,90.3 L78.6,69.8 V28.6 l-38.8,-22.6"/>
      <path id="fill-right"
            d="M8,69.8 L43.3,90.3 L78.6,69.8 V28.6 l-38.8,-22.6"/>
    </g>
  </svg>
</div>

关于html - SVG 动画最后没有正确关闭(小间隙仍然存在),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43238952/

相关文章:

html - 使用 css 制作加号

jquery - Raphael JS 工具提示在第一次悬停时不显示

jquery - 使用 Jquery 的 mouseenter 和 mouseleave 文件上传按钮闪烁

html - 溢出自动和高度在移动版 Chrome 中不起作用

html - 如何避免使用 `inline-block` 元素换行

javascript - 使 SVG 完全填满整个页面

css - 如何将线性渐变应用于 <use> 标签中的 SVG <symbol>?

javascript - HTML 表单上的默认提交按钮是如何确定的?

php - Kriesi 分页不起作用

html - 当内容进入时,div 的宽度被忽略