我对 SVG 比较陌生。尝试实现六边形加载器,90% 已经完成,但在动画结束时六边形没有完全闭合(仍然存在一个小间隙)。实际上,我使用 Adobe 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/