【问题标题】:SVG vector text stroke is not "finished"SVG 矢量文本笔划未“完成”
【发布时间】:2020-12-01 01:09:10
【问题描述】:

为什么我的矢量文本上的这个笔划没有在某些字母角上完成?我在 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>

【问题讨论】:

    标签: html svg text path stroke


    【解决方案1】:

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

    您使用的路径以 closepath 命令 z 结束其 d 属性。 spec 清楚地表明,无论是否使用 closepath,路径端点处的笔划行为都会有所不同:

    当子路径以“closepath”结尾时,它的行为与通过“lineto”命令“手动”关闭子路径时的行为不同,stroke-linejoinstroke-linecap 的实现方式。使用“closepath”,子路径的最后一段的结尾使用stroke-linejoin 的当前值与子路径的初始段的开始“连接”。如果您改为通过“lineto”命令“手动”关闭子路径,则第一个段的开头和最后一个段的结尾不会连接,而是使用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,这意味着笔划只是垂直于笔划的末端而结束。因此,在不关闭路径的情况下,在外角处会保留一个间隙,如果应用 linejoin,则会绘制一个斜接。

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

    而位置

    1. 将索引设置为 (index + 1) 模数。
    2. 令 dashlength 为 min(dashesindex, pathlength - position)。
    3. 如果 index mod 2 = 0,则将 对附加到位置。
    4. 将位置设置为位置 + dashlength。

    没有。 2 表示,最后一个破折号总是在路径之前或结尾处结束,并且永远不会过冲。作为一种算法,这是有道理的。但规范还规定,每个破折号以stroke-linecap 定义的大写形状开始和结束。

    1. 让位置为子路径的破折号位置。

    2. 对于每对 的位置:(...)

      1. 将 dash 设置为 dash 和 start 位置处子路径的起始帽形状的并集。

      2. 将 dash 设置为 dash 和 end 位置处子路径的结束帽形状的并集。

      3. 设 index 和 last 是子路径中路径段的索引,距离起点和终点沿子路径。

      4. 而索引

        1. 将 dash 设置为 dash 和段索引索引处子路径的线连接形状的并集。
        2. 将索引设置为索引 + 1。

    它没有提到封闭路径的开始和结束作为特例。 Linejoin 的形状仅在 破折号内绘制,但在它们的末端总是绘制一个 cap 形状,而不是 join 形状。 p>

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

    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>

    【讨论】:

    • 感谢您的详细回答。获得的关于 SVG 的信息比我预期的要多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 1970-01-01
    • 2015-10-29
    • 2013-02-12
    相关资源
    最近更新 更多