这是使用光栅化策略的结果,没有简单的解决方法。
一种解决方法是描边三角形,但描边非常非常细。例如,这里有一个 0.2px 的描边:
或者,您可以将您的图形加倍并在实际内容下方渲染描边版本。
<g id="underlay">
<polygon class="t1" points="10,10 10,390 390,390 10,10" />
<polygon class="t2" points="10,10 390,390 390,10 10,10" />
</g><g id="content">
<polygon class="t1" points="10,10 10,390 390,390 10,10" />
<polygon class="t2" points="10,10 390,390 390,10 10,10" />
</g>
.t1 { fill:rgb(140,90,90); stroke:rgb(140,90,90) }
.t2 { fill:rgb(90,140,90); stroke:rgb(90,140,90) }
#underlay polygon { stroke-width:1px }
#content polygon { stroke:none }
(如果您在用户代理(如可用的网络浏览器)中运行,则可以通过 JS 自动执行此操作。)
这个演示非常清楚地显示了这个问题。
<svg xmlns="http://www.w3.org/2000/svg">
<g id="aligned">
<polygon class="a" points="10,10 10,100 100,100, 100,10" />
<polygon class="b" points="100,10 100,100 200,100, 200,10" />
</g>
<g id="shifted" transform="translate(0.5,110)">
<polygon class="a" points="10,10 10,100 100,100, 100,10" />
<polygon class="b" points="100,10 100,100 200,100, 200,10" />
</g>
</svg>
在这里,我们有两个垂直边缘正好在彼此的顶部。在第一种情况下,它们在像素网格上完全对齐。左侧形状完全填充左侧的所有像素,右侧形状完全填充右侧的所有像素,并且都不填充间隙。
然而,在第二种情况下,两个形状都位于像素边界之间。由于我们的形状与这些像素重叠了 50%,因此抗锯齿告诉我们,在这种情况下,我们应该将重叠的像素填充为 50% 的不透明度。所以左边的形状用 50% 的不透明度填充这个共享的像素列,然后右边的形状用另外 50% 的不透明度填充共享的列。
不幸的是,不透明度是通过乘法而不是加法建立的。一个像素的rgba(0,0,0,0.5)
overtoprgba(0,0,0,0.5)
产生rgba(0,0,0,0.75)
,NOT rgba(0,0,0,1)
。
这是问题的症结所在,它并不特定于 SVG。例如,请参阅:
当您将无限精确的矢量图像采样到有限像素网格时,信息会丢失。你需要破解它来解决它。