我创建了一个树状结构的卡片,父母和孩子之间有线条。这些线是 svg 路径,如下所示:
const newpath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
newpath.setAttributeNS(
null,
'd',
`M${parentX} ${parentY} h10 a${arcRadius},${arcRadius} 0 0 1 ${arcRadius},${arcRadius} v ${
childY - arcRadius * 2
} a${arcRadius},${arcRadius} 0 0 0 ${arcRadius},${arcRadius} h12`
);
newpath.setAttributeNS(null, 'stroke', 'black');
newpath.setAttributeNS(null, 'stroke-width', '1');
newpath.setAttributeNS(null, 'opacity', '1');
newpath.setAttributeNS(null, 'fill', 'none');
现在这意味着对于 1 个父级和 3 个子级,将创建 3 条路径。所有 3 条路径都与第一个子项重叠,2 条路径与第二个子项重叠,最后有 1 条路径与第三个子项重叠。通过调整transform:scale()属性,整个树是可缩放的。现在,当我缩小时,重叠的线条会变暗。除了只在孩子之间画线之外,还有什么方法可以摆脱这种行为吗?
这里之前已经问过类似的问题:为什么彼此之上的 SVG 线条/路径会创建不同的笔划?但接受的解决方案对我不起作用。
不幸的是,没有完美的解决方案。
在清晰度和平滑边缘之间提供适当平衡的解决方法可能是应用 svg
feComponentTransfer
滤镜 来增强 Alpha 通道的对比度。
svg{
border: 1px solid #ccc;
width: 70px;
}
path{
stroke-width:1px;
fill:none;
}
.crisp path{
shape-rendering: crispEdges
}
.contrast
path{
filter:url(#enhanceContrast);
}
<h3>Unedited</h3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" >
<path stroke="#000" d="M46.694,63.025c-6.627,0-12-5.373-12-12V16.248"/>
<path stroke="#000" d="M46.694,76.536c-6.627,0-12-5.373-12-12V29.758"/>
<path stroke="#000" d="M46.694,89.753c-6.627,0-12-5.373-12-12V42.975"/>
</svg>
<h3>shape-rendering: crispedges</h3>
<svg class="crisp" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" >
<path stroke="#000" d="M46.694,63.025c-6.627,0-12-5.373-12-12V16.248"/>
<path stroke="#000" d="M46.694,76.536c-6.627,0-12-5.373-12-12V29.758"/>
<path stroke="#000" d="M46.694,89.753c-6.627,0-12-5.373-12-12V42.975"/>
</svg>
<h3>Integer coordinates</h3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path stroke="#000" d="M 47 63
c -7 0 -12 -5 -12 -12
v -35"/>
<path stroke="#000" d="M 47 77
c -7 0 -12 -5 -12 -12
v -35"/>
<path stroke="#000" d="M 47 90
c -7 0 -12 -5 -12 -12
v -35"/>
</svg>
<h3>Duplicate strokes</h3>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<path stroke="#000" d="M 47 63
c -7 0 -12 -5 -12 -12
v -35"/>
<path stroke="#000" d="M 47 77
c -7 0 -12 -5 -12 -12
v -35"/>
<path stroke="#000" d="M 47 90
c -7 0 -12 -5 -12 -12
v -35"/>
<path stroke="#000" d="M 47 63
c -7 0 -12 -5 -12 -12
v -35"/>
<path stroke="#000" d="M 47 77
c -7 0 -12 -5 -12 -12
v -35"/>
<path stroke="#000" d="M 47 90
c -7 0 -12 -5 -12 -12
v -35"/>
</svg>
<h3>Enhance contrast (svg filter)</h3>
<svg class="contrast" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" >
<path stroke="#000" d="M46.694,63.025c-6.627,0-12-5.373-12-12V16.248"/>
<path stroke="#000" d="M46.694,76.536c-6.627,0-12-5.373-12-12V29.758"/>
<path stroke="#000" d="M46.694,89.753c-6.627,0-12-5.373-12-12V42.975"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" style="position: fixed; width:0; height:0; overflow:hidden;">
<filter id="enhanceContrast" x="0" y="0" width="100%" height="100%">
<feComponentTransfer>
<feFuncA type="gamma" amplitude="1" exponent="1" offset="0"></feFuncA>
</feComponentTransfer>
</filter>
</svg>
上面的示例比较了不同的解决方法:
shape-rendering: crispEdges
– 非常适合直线,但会在曲线上产生锯齿状边缘feComponentTransfer
滤镜增强 alpha 对比度:我们基本上减少了半透明像素的数量。