SVG填充路径 - 如果它自身循环,则不会填充重叠

时间:2017-11-03 07:49:55

标签: svg

我维护一个用闪存编写的绘图工具,它将高光工具的数据保存为一系列描述粗填充徒手/点对点线轮廓的点。例如,如果用户绘制了一条水平线,则路径将是从左到右的一系列点,然后是一条向下10像素的线,相反的点序列反向回到原点以下10px,然后他的路径是关闭

另一个工具通过将json点列表转换为svg路径来定期光栅化flash的数据。路径命令类似于" M 123,456 l 1,2 3,5 -2,-5 ......"并描述了形状的完整外边缘。没有中风,填充是不透明度0.4

我注意到如果用户绘制了一条与自身重叠的线,就像希腊符号alpha那样,重叠部分就不会被填充。我期待它变得更加不透明,就像真正的荧光笔一样。

这种行为是否在SVG中设计?或者它可能是我使用的库中的错误?如果按照设计,我可以使用什么替代策略来渲染部分不透明的荧光笔线,如果它穿过自身会逐渐变得更不透明?

我应该注意,两个单独的行(svg doc包含两个交叉的路径元素)相互绘制DO变得更加不透明,正如它的单个路径元素,这种奇怪的行为发生

以下是演示行为的示例SVG文档。它可以在http://www.rapidtables.com/web/tools/svg-viewer-editor.htm之类的内容中显示(将代码粘贴到顶部文本框中,然后单击放大镜图标。需要一个能够理解SVG的浏览器)



    <svg width="680" height="465" version="1.1" xmlns="http://www.w3.org/2000/svg">
      <g>
        <path d="M 283,29 l -2,2 -1,1 -5,4 -5,4 -4,3 -4,2 -3,2 -4,3 -6,3 -4,2 -5,3 -6,5 -3,2 -4,2 -1,1 -5,2 -4,3 -4,2 -3,1 -3,2 -3,2 -4,1 -8,3 -3,1 -5,1 -6,1 -1,0 -5,1 -4,0 -5,0 -6,1 -6,0 -7,0 -10,0 -7,0 -7,0 -5,0 -5,0 -9,0 -2,0 -3,0 -8,0 -3,0 -6,0 -4,0 -4,0 -3,-1 -3,-1 -2,-2 -2,-1 -3,-4 0,-1 -2,-3 -2,-4 -1,-2 -1,-3 -1,-5 0,-6 0,-4 0,-4 0,-4 0,-5 0,-5 0,-4 1,-4 3,-4 3,-4 2,-3 2,-3 2,-2 1,-1 3,-1 2,-1 2,-1 8,-3 7,-1 5,-1 4,0 3,0 3,0 2,0 2,0 2,0 2,0 3,0 2,0 3,0 2,0 5,0 3,0 1,0 2,0 3,1 4,2 3,0 2,2 4,2 4,2 3,1 2,2 2,2 3,2 4,3 3,3 2,2 3,3 2,3 2,2 2,3 1,3 2,3 2,3 3,3 2,3 1,3 2,3 2,3 2,3 2,3 1,3 1,3 2,2 2,2 2,3 1,3 3,3 2,3 1,2 2,1 1,2 2,1 2,2 3,1 2,1 2,2 2,1 3,1 3,1 2,2 3,1 4,2 4,2 3,1 3,1 3,1 3,0 2,1 2,1 2,0 4,1 4,1 4,0 3,0 3,0 4,0 2,0 4,0 3,0 1,0 2,0 3,0 3,0 2,0 2,0 3,0 2,0 2,0 1,0 1,-1 1,0 2,-1 2,0 2,-1 1,0 1,-1 1,0 1,-1 1,0 1,0 0,25 -1,0 -1,0 -1,1 -1,0 -1,1 -1,0 -2,1 -2,0 -2,1 -1,0 -1,1 -1,0 -2,0 -2,0 -3,0 -2,0 -2,0 -3,0 -3,0 -2,0 -1,0 -3,0 -4,0 -2,0 -4,0 -3,0 -3,0 -4,0 -4,-1 -4,-1 -2,0 -2,-1 -2,-1 -3,0 -3,-1 -3,-1 -3,-1 -4,-2 -4,-2 -3,-1 -2,-2 -3,-1 -3,-1 -2,-1 -2,-2 -2,-1 -3,-1 -2,-2 -2,-1 -1,-2 -2,-1 -1,-2 -2,-3 -3,-3 -1,-3 -2,-3 -2,-2 -2,-2 -1,-3 -1,-3 -2,-3 -2,-3 -2,-3 -2,-3 -1,-3 -2,-3 -3,-3 -2,-3 -2,-3 -1,-3 -2,-3 -2,-2 -2,-3 -3,-3 -2,-2 -3,-3 -4,-3 -3,-2 -2,-2 -2,-2 -3,-1 -4,-2 -4,-2 -2,-2 -3,0 -4,-2 -3,-1 -2,0 -1,0 -3,0 -5,0 -2,0 -3,0 -2,0 -3,0 -2,0 -2,0 -2,0 -2,0 -3,0 -3,0 -4,0 -5,1 -7,1 -8,3 -2,1 -2,1 -3,1 -1,1 -2,2 -2,3 -2,3 -3,4 -3,4 -1,4 0,4 0,5 0,5 0,4 0,4 0,4 0,6 1,5 1,3 1,2 2,4 2,3 0,1 3,4 2,1 2,2 3,1 3,1 4,0 4,0 6,0 3,0 8,0 3,0 2,0 9,0 5,0 5,0 7,0 7,0 10,0 7,0 6,0 6,-1 5,0 4,0 5,-1 1,0 6,-1 5,-1 3,-1 8,-3 4,-1 3,-2 3,-2 3,-1 4,-2 4,-3 5,-2 1,-1 4,-2 3,-2 6,-5 5,-3 4,-2 6,-3 4,-3 3,-2 4,-2 4,-3 5,-4 5,-4 1,-1 2,-2" style="stroke-linecap: round; stroke-linejoin: round; fill: #0000CC; fill-opacity: 0.4; fill-rule: evenodd; stroke: none" />
    
        <path d="M 583,29 l -2,2 -1,1 -5,4 -5,4 -4,3 -4,2 -3,2 -4,3 -6,3 -4,2 -5,3 -6,5 -3,2 -4,2 -1,1 -5,2 -4,3 -4,2 -3,1 -3,2 -3,2 -4,1 -8,3 -3,1 -5,1 -6,1 -1,0 -5,1 -4,0 -5,0 -6,1 -6,0 -7,0 -10,0 -7,0 -7,0 -5,0 -5,0 -9,0 -2,0 -3,0 -8,0 -3,0 -6,0 -4,0 -4,0 -3,-1 -3,-1 -2,-2 -2,-1 -3,-4 0,-1 -2,-3 -2,-4 -1,-2 -1,-3 -1,-5 0,-6 0,-4 0,-4 0,-4 0,-5 0,-5 0,-4 1,-4 3,-4 3,-4 2,-3 2,-3 2,-2 1,-1 3,-1 2,-1 2,-1 8,-3 7,-1 5,-1 4,0 3,0 3,0 2,0 2,0 2,0 2,0 3,0 2,0 3,0 2,0 5,0 3,0 1,0 2,0 3,1 4,2 3,0 2,2 4,2 4,2 3,1 2,2 2,2 3,2 4,3 3,3 2,2 3,3 2,3 2,2 2,3 1,3 2,3 2,3 3,3 2,3 1,3 2,3 2,3 2,3 2,3 1,3 1,3 2,2 2,2 2,3 1,3 3,3 2,3 1,2 2,1 1,2 2,1 2,2 3,1 2,1 2,2 2,1 3,1 3,1 2,2 3,1 4,2 4,2 3,1 3,1 3,1 3,0 2,1 2,1 2,0 4,1 4,1 4,0 3,0 3,0 4,0 2,0 4,0 3,0 1,0 2,0 3,0 3,0 2,0 2,0 3,0 2,0 2,0 1,0 1,-1 1,0 2,-1 2,0 2,-1 1,0 1,-1 1,0 1,-1 1,0 1,0 0,25 -1,0 -1,0 -1,1 -1,0 -1,1 -1,0 -2,1 -2,0 -2,1 -1,0 -1,1 -1,0 -2,0 -2,0 -3,0 -2,0 -2,0 -3,0 -3,0 -2,0 -1,0 -3,0 -4,0 -2,0 -4,0 -3,0 -3,0 -4,0 -4,-1 -4,-1 -2,0 -2,-1 -2,-1 -3,0 -3,-1 -3,-1 -3,-1 -4,-2 -4,-2 -3,-1 -2,-2 -3,-1 -3,-1 -2,-1 -2,-2 -2,-1 -3,-1 -2,-2 -2,-1 -1,-2 -2,-1 -1,-2 -2,-3 -3,-3 -1,-3 -2,-3 -2,-2 -2,-2 -1,-3 -1,-3 -2,-3 -2,-3 -2,-3 -2,-3 -1,-3 -2,-3 -3,-3 -2,-3 -2,-3 -1,-3 -2,-3 -2,-2 -2,-3 -3,-3 -2,-2 -3,-3 -4,-3 -3,-2 -2,-2 -2,-2 -3,-1 -4,-2 -4,-2 -2,-2 -3,0 -4,-2 -3,-1 -2,0 -1,0 -3,0 -5,0 -2,0 -3,0 -2,0 -3,0 -2,0 -2,0 -2,0 -2,0 -3,0 -3,0 -4,0 -5,1 -7,1 -8,3 -2,1 -2,1 -3,1 -1,1 -2,2 -2,3 -2,3 -3,4 -3,4 -1,4 0,4 0,5 0,5 0,4 0,4 0,4 0,6 1,5 1,3 1,2 2,4 2,3 0,1 3,4 2,1 2,2 3,1 3,1 4,0 4,0 6,0 3,0 8,0 3,0 2,0 9,0 5,0 5,0 7,0 7,0 10,0 7,0 6,0 6,-1 5,0 4,0 5,-1 1,0 6,-1 5,-1 3,-1 8,-3 4,-1 3,-2 3,-2 3,-1 4,-2 4,-3 5,-2 1,-1 4,-2 3,-2 6,-5 5,-3 4,-2 6,-3 4,-3 3,-2 4,-2 4,-3 5,-4 5,-4 1,-1 2,-2" style="stroke-linecap: round; stroke-linejoin: round; fill: #0000CC; fill-opacity: 0.4; fill-rule: nonzero; stroke: none" />
      </g>
    </svg>
&#13;
&#13;
&#13;

关于注释:doc基本上使用填充路径绘制两个alpha符号,尽管每个符号的fill-rule不同。外观上没有明显的差异,但是对于更复杂的形状,它们会多次交叉回来,输出会有所不同 - 所有的例子都无法复制一个荧光笔,只要填充区域经过一个就会变暗。已经填充的相同路径的区域

1 个答案:

答案 0 :(得分:2)

我现在明白你的问题。不幸的是fill-rule: nonzero对你的情况没有帮助,因为你的路径不只是自相交(通常会很好),但它也会在左侧交叉。这会弄乱填充规则“非零”算法。

也没有一个简单的解决方案。我能建议的最好的方法是检测荧光笔路径何时到达水平拐点(即水平改变方向),然后将路径分成两个路径(或子路径)。