SVG 在浏览器中制作白线

SVG makes white lines in the browser

我制作了一个 24x24 像素的徽标。它由并排的多边形组成。

我在我的网页上以 40 像素24 像素.[=14 范围内的各种尺寸显示=]

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="katman_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<polygon points="6,20 4,16 2,20 "/>
<polygon points="4,16 2,12 0,16 "/>
<polygon points="6,12 4,8 2,12 "/>
<polygon points="8,8 6,4 4,8 "/>
<polygon points="10,12 8,8 6,12 "/>
<polygon points="14,12 12,8 10,12 "/>
<polygon points="18,12 16,8 14,12 "/>
<polygon points="22,12 20,8 18,12 "/>
<polygon points="12,16 10,12 8,16 "/>
<polygon points="20,16 18,12 16,16 "/>
<polygon points="4,16 6,20 8,16 "/>
<polygon points="2,12 4,16 6,12 "/>
<polygon points="0,16 2,20 4,16 "/>
<polygon points="4,8 6,12 8,8 "/>
<polygon points="6,4 8,8 10,4 "/>
<polygon points="8,8 10,12 12,8 "/>
<polygon points="16,8 18,12 20,8 "/>
<polygon points="18,12 20,16 22,12 "/>
<polygon points="10,12 12,16 14,12 "/>
<polygon points="8,16 10,20 12,16 "/>
<polygon points="16,16 18,20 20,16 "/>
<polygon points="20,16 22,20 24,16 "/>
<polygon points="10,20 8,16 6,20 "/>
<polygon points="14,20 12,16 10,20 "/>
<polygon points="18,20 16,16 14,20 "/>
<polygon points="22,20 20,16 18,20 "/>
</svg>

但是 svg 元素之间形成了白线... 例如:

原始 svg 文件:bz.svg

我无法将它们组合起来,因为在某些情况下我会分别为每一个着色。我该如何解决这个问题?

Shape Rendering 是你的罪魁祸首朋友。

只需将 shape-rendering="crispEdges" 添加到 svg 声明中(参见下面的源示例)... ....或者 CSS 如果你喜欢在元素级别点击多个;

svg {
  shape-rendering: crispEdges;
}

欣赏精美的图片 ;)

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="katman_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve" 
shape-rendering="crispEdges"> <!-- **** YOUR NEW FRIEND **** -->
  <polygon points="6,20 4,16 2,20 "/>
  <polygon points="4,16 2,12 0,16 "/>
  <polygon points="6,12 4,8 2,12 "/>
  <polygon points="8,8 6,4 4,8 "/>
  <polygon points="10,12 8,8 6,12 "/>
  <polygon points="14,12 12,8 10,12 "/>
  <polygon points="18,12 16,8 14,12 "/>
  <polygon points="22,12 20,8 18,12 "/>
  <polygon points="12,16 10,12 8,16 "/>
  <polygon points="20,16 18,12 16,16 "/>
  <polygon points="4,16 6,20 8,16 "/>
  <polygon points="2,12 4,16 6,12 "/>
  <polygon points="0,16 2,20 4,16 "/>
  <polygon points="4,8 6,12 8,8 "/>
  <polygon points="6,4 8,8 10,4 "/>
  <polygon points="8,8 10,12 12,8 "/>
  <polygon points="16,8 18,12 20,8 "/>
  <polygon points="18,12 20,16 22,12 "/>
  <polygon points="10,12 12,16 14,12 "/>
  <polygon points="8,16 10,20 12,16 "/>
  <polygon points="16,16 18,20 20,16 "/>
  <polygon points="20,16 22,20 24,16 "/>
  <polygon points="10,20 8,16 6,20 "/>
  <polygon points="14,20 12,16 10,20 "/>
  <polygon points="18,20 16,16 14,20 "/>
  <polygon points="22,20 20,16 18,20 "/>
</svg>

shape-rendering 在大多数情况下会有帮助。但这并不能保证。您仍然可能会发现奇怪的白色像素。此外,它的缺点是您会失去外边缘的抗锯齿功能。留下斜边 "jaggy".

正如其他人所建议的那样,另一种解决方案是为您的形状添加细笔触。该笔画所需的宽度将取决于连接线的斜率和浏览器使用的 2D 渲染引擎。

第三种解决方案是合并颜色相同的相邻三角形。您可以写一点 javascript 来进行合并。您可能不必担心具有不同颜色的相邻三角形。如果颜色足够不同,那条轻微的白线可能不会很明显。

第四个选项类似。不是合并三角形,而是寻找后面三角形邻接的三角形边,并给这些边一个 "bulge"。例如,通过在该侧的中间使用一个额外的点,它会突出一点。这个想法是前面的三角形延伸到后面的三角形下面。

我能想到的一个最终解决方案是 运行 在形状上添加一个过滤器以消除抗锯齿伪影。

理想的滤波器是中值滤波器,但不幸的是,SVG/CSS 没有中值滤波器。 Michael Mullany 创建了 a very clever hack,它使用可用的滤波器原语组合来模拟中值滤波器。

<svg version="1.1" id="katman_1" viewBox="0 0 24 24">
  <defs>
    <filter id="median">
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 1 0 0 0 0 0" result="1" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="1 0 0 0 0 0 0 0 0" result="2" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 1 0 0 0 0 0 0 0" result="3" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 1 0 0 0 0 0 0" result="4" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 1 0 0 0" result="5" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 0 0 1" result="6" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 0 1 0" result="7" preserveAlpha="true"/>
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 0 0 1 0 0" result="8" preserveAlpha="true" />
      <feConvolveMatrix in="SourceGraphic" order="3" kernelMatrix="0 0 0 0 1 0 0 0 0" result="9" preserveAlpha="true" />
      <feBlend in="1" in2="2" mode="lighten" result="a1"/>
      <feBlend in="1" in2="2" mode="darken" result="a2"/>
      <feBlend in="a2" in2="3" mode="lighten" result="a3"/>
      <feBlend in="a2" in2="3" mode="darken" result="a4"/>
      <feBlend in="a4" in2="4" mode="lighten" result="a5"/>
      <feBlend in="a4" in2="4" mode="darken" result="a6"/>
      <feBlend in="a6" in2="5" mode="lighten" result="a7"/>
      <feBlend in="a6" in2="5" mode="darken" result="a8"/>
      <feBlend in="a8" in2="6" mode="lighten" result="a9"/>
      <feBlend in="a8" in2="6" mode="darken" result="a10"/>
      <feBlend in="a10" in2="7" mode="lighten" result="a11"/>
      <feBlend in="a10" in2="7" mode="darken" result="a12"/>
      <feBlend in="a12" in2="8" mode="lighten" result="a13"/>
      <feBlend in="a13" in2="8" mode="darken" result="a14"/>
      <feBlend in="1" in2="2" mode="lighten" result="a15"/>
      <feBlend in="1" in2="2" mode="darken" result="a16"/>    
      <feBlend in="a1" in2="a3" mode="lighten" result="b1"/>
      <feBlend in="a1" in2="a3" mode="darken" result="b2"/>
      <feBlend in="b2" in2="a5" mode="lighten" result="b3"/>
      <feBlend in="b2" in2="a5" mode="darken" result="b4"/>
      <feBlend in="b4" in2="a7" mode="lighten" result="b5"/>
      <feBlend in="b4" in2="a7" mode="darken" result="b6"/>
      <feBlend in="b6" in2="a9" mode="lighten" result="b7"/>
      <feBlend in="b6" in2="a9" mode="darken" result="b8"/>
      <feBlend in="b8" in2="a11" mode="lighten" result="b9"/>
      <feBlend in="b8" in2="a11" mode="darken" result="b10"/>
      <feBlend in="b10" in2="a13" mode="lighten" result="b11"/>
      <feBlend in="b10" in2="a13" mode="darken" result="b12"/>
      <feBlend in="b12" in2="a15" mode="lighten" result="b13"/>
      <feBlend in="b12" in2="a15" mode="darken" result="b14"/>
      <feBlend in="b1" in2="b3" mode="lighten" result="c1"/>
      <feBlend in="b1" in2="b3" mode="darken" result="c2"/>
      <feBlend in="c2" in2="b5" mode="lighten" result="c3"/>
      <feBlend in="c2" in2="b5" mode="darken" result="c4"/>
      <feBlend in="c4" in2="b7" mode="lighten" result="c5"/>
      <feBlend in="c4" in2="b7" mode="darken" result="c6"/>
      <feBlend in="c6" in2="b9" mode="lighten" result="c7"/>
      <feBlend in="c6" in2="b9" mode="darken" result="c8"/>
      <feBlend in="c8" in2="b11" mode="lighten" result="c9"/>
      <feBlend in="c8" in2="b11" mode="darken" result="c10"/>
      <feBlend in="c10" in2="b13" mode="lighten" result="c11"/>
      <feBlend in="c10" in2="b13" mode="darken" result="c12"/>
      <feBlend in="c1" in2="c3" mode="lighten" result="d1"/>
      <feBlend in="d1" in2="c3" mode="darken" result="d2"/>
      <feBlend in="d2" in2="c5" mode="lighten" result="d3"/>
      <feBlend in="d2" in2="c5" mode="darken" result="d4"/>
      <feBlend in="d4" in2="c7" mode="lighten" result="d5"/>
      <feBlend in="d4" in2="c7" mode="darken" result="d6"/>
      <feBlend in="d6" in2="c9" mode="lighten" result="d7"/>
      <feBlend in="d6" in2="c9" mode="darken" result="d8"/>
      <feBlend in="d8" in2="c11" mode="lighten" result="d9"/>
      <feBlend in="d8" in2="c11" mode="darken" result="d10"/>
      <feBlend in="d1" in2="d3" mode="darken" result="e1"/>
      <feBlend in="e1" in2="d5" mode="darken" result="e2"/>
      <feBlend in="e2" in2="d7" mode="darken" result="e3"/>
      <feBlend in="e3" in2="d9" mode="darken" result="e4"/>
    </filter>
  </defs>

  <g filter="url(#median)">
    <polygon points="6,20 4,16 2,20 "/>
    <polygon points="4,16 2,12 0,16 "/>
    <polygon points="6,12 4,8 2,12 "/>
    <polygon points="8,8 6,4 4,8 "/>
    <polygon points="10,12 8,8 6,12 "/>
    <polygon points="14,12 12,8 10,12 "/>
    <polygon points="18,12 16,8 14,12 "/>
    <polygon points="22,12 20,8 18,12 "/>
    <polygon points="12,16 10,12 8,16 "/>
    <polygon points="20,16 18,12 16,16 "/>
    <polygon points="4,16 6,20 8,16 "/>
    <polygon points="2,12 4,16 6,12 "/>
    <polygon points="0,16 2,20 4,16 "/>
    <polygon points="4,8 6,12 8,8 "/>
    <polygon points="6,4 8,8 10,4 "/>
    <polygon points="8,8 10,12 12,8 "/>
    <polygon points="16,8 18,12 20,8 "/>
    <polygon points="18,12 20,16 22,12 "/>
    <polygon points="10,12 12,16 14,12 "/>
    <polygon points="8,16 10,20 12,16 "/>
    <polygon points="16,16 18,20 20,16 "/>
    <polygon points="20,16 22,20 24,16 "/>
    <polygon points="10,20 8,16 6,20 "/>
    <polygon points="14,20 12,16 10,20 "/>
    <polygon points="18,20 16,16 14,20 "/>
    <polygon points="22,20 20,16 18,20 "/>
  </g>
</svg>