SVG矢量文字笔画不是"finished"

SVG vector text stroke is not "finished"

为什么我的矢量文本上的这一笔画在某些字母角上没有完成?我在 Illustrator 中用 1px 笔划制作了这个 SVG,作为图片它应该是这样的。我尝试了不同的字体,但我仍然遇到同样的问题。我还尝试了矢量效果:非缩放笔划;这有点帮助。我测试了不同的 stroke-dashoffsets 但也没有成功。

here is an example

path{
stroke-dasharray:500;
opacity:10;
stroke:#000;
animation: animate 4s cubic-bezier(.69,.71,.69,.71);
}

@keyframes animate{
    
    0%{

        opacity=0;
    stroke-dashoffset:500;
    }
    
20%{

        opacity=0;
    stroke-dashoffset:500;
    }
    

        100%{
        opacity:10;
    stroke-dashoffset:0;
    
    }
    
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 363.5 122.5" style="enable-background:new 0 0 363.5 122.5;" xml:space="preserve">
<style type="text/css">
    .st0{fill:#AF174A;}
    .st1{stroke:#000000;stroke-miterlimit:10;}
</style>
<polygon class="st0" points="189.6,-14.4 189.5,-14.5 189.5,-14.4 "/>
<g>
    <path class="st1" d="M121.9,104.7l-18.1-17.8v17.8h-1.1V67.4h1.1v17.9l18.1-17.9h1.4l-18.9,18.7l18.9,18.7H121.9z"/>
    <path class="st1" d="M148.7,67.4v1h-17.2v17.2h15.6v1h-15.6v17.2h17.2v1h-18.2V67.4H148.7z"/>
    <path class="st1" d="M164.8,104.7l-10-37.3h1.2l9.4,35.2l10.9-35.2h1.2l11,35.4l9.4-35.4h1.2l-10,37.3h-1.1l-11.1-35.6l-11.1,35.6
        H164.8z"/>
    <path class="st1" d="M225.2,67.4v1H208v17.2h15.6v1H208v17.2h17.2v1H207V67.4H225.2z"/>
    <path class="st1" d="M258.2,67.5h1.1v37.3h-1.1L235,69.4v35.3h-1.1V67.5h1.1l23.2,35.3V67.5z"/>
</g>
</svg>

您被我不太确定的 SVG 规范细节所困扰。这是错误还是功能?自己决定。

您使用的路径以 closepath 命令结束其 d 属性 zspec 清楚地表明,无论是否使用 closepath,路径终点处的笔画行为都不同:

When a subpath ends in a "closepath," it differs in behavior from what happens when "manually" closing a subpath via a "lineto" command in how stroke-linejoin and stroke-linecap are implemented. With "closepath", the end of the final segment of the subpath is "joined" with the start of the initial segment of the subpath using the current value of stroke-linejoin. If you instead "manually" close the subpath via a "lineto" command, the start of the first segment and the end of the last segment are not joined but instead are each capped using the current value of stroke-linecap.

你可以在下面的例子中比较关闭和不关闭路径的效果。

path {
    fill: none;
    stroke: black;
    stroke-width: 20;
}
<svg viewBox="0 0 300 100">
    <path d="M20 20 H 80 V 80 H 20 V 20" />
    <path d="M120 20 H 180 V 80 H 120 z" />
</svg>

stroke-linecap 的默认值是 butt,这意味着笔画只是垂直于笔画的末端结束。因此,在不关闭路径的情况下,在外角仍然存在间隙,如果应用线连接,则会绘制斜接。

现在,您的代码具有 closepath 命令。为什么最终的斜角没有被绘制出来?您必须仔细阅读 spec 以了解其绘制破折号的算法。在计算破折号的位置时,它说

While position < pathlength:

  1. Set index to (index + 1) mod count.
  2. Let dashlength be min(dashesindex, pathlength − position).
  3. If index mod 2 = 0, then append to positions the pair <position, position + dashlength>.
  4. Set position to position + dashlength.

没有。 2 意味着,最后一个破折号总是在路径之前或路径的末尾结束,并且永远不会超过。作为一种算法,这是有道理的。但是规范还说每个破折号的开始和结束都由 stroke-linecap.

定义的帽形
  1. Let positions be the dash positions for the subpath.

  2. For each pair <start, end> in positions: (...)

    1. Set dash to be the union of dash and the starting cap shape for the subpath at position start.

    2. Set dash to be the union of dash and the ending cap shape for the subpath at position end.

    3. Let index and last be the indexes of the path segments in the subpath at distance start and end along the subpath.

    4. While index < last:

      1. Set dash to be the union of dash and the line join shape for the subpath at segment index index.
      2. Set index to index + 1.

它没有提到封闭路径的起点和终点作为特例。 Linejoin 的形状仅绘制在 inside 破折号处,但始终在其末端绘制 cap 形状,从来没有 join 形状。

这导致回答者 建议使用 stroke-linecap: square。只要路径的第一段和最后一段垂直相交,这种方法就可以很好地工作。但是如果有任何其他角度,比如字母 K 和 W,您仍然会得到不正确的结果。 round 的值看起来很平滑,但也不同于其他 linejoins 上的斜接效果。

path {
    fill: none;
    stroke: black;
    stroke-width: 20;
    stroke-dasharray: 250;
    stroke-linecap: square;
}
.smoothed {
   stroke-linecap: round;
}
<svg viewBox="0 0 300 100">
    <path d="M20 20 H 80 V 80 H 20 z" />
    <path d="M120 20 H 180 V 80 H 140 z" />
    <path d="M220 20 H 280 V 80 H 240 z" class="smoothed" />
</svg>