Reputation:
I would like to know how to highlight (change the color) a self overlapping zone of an SVG path (or even polyline). Actually, if i change the opacity and stroke property of a path the self ovverlaping zone has no change in color.
For example, having the following path <path d="M187 240 L188 240 L315 217 L317 217 L330 306 L247 233 L258 226 L292 222 L303 178 L353 165" fill="none" opacity="0.6" stroke-width="14" stroke = "red"/>
, the overlapping zone is not red-dark.
Here is what i've found so far but doesn't help me with the issue.
http://www.svgopen.org/2005/papers/abstractsvgopen/index.html#S2.
thanks
Upvotes: 4
Views: 2005
Reputation: 31715
Here's a version that works for you (although it makes the lines a bit crispier than we'd like). It takes what Paul has suggested, but improves it by using 2-segment lines so the line joins are rendered correctly, then it uses a filter to select and recolor the high opacity areas that overlap. The table values are set exactly to select in just the true overlap and select out the small overlap artifacts caused at line joins by the fact that we're double-drawing. You could probably add a very small blur to "hand anti-alias" the final line.
<svg width="800px" height="600px" viewBox= "0 0 800 600">
<defs>
<filter id="overlappy">
<feComponentTransfer result="overlap">
<feFuncA type="table" tableValues="0 0 0 0 0 0 0 0 1"/>
</feComponentTransfer>
<feColorMatrix in="overlap" result="solid-blue" type="matrix" values ="0 0 0 0 0
0 0 0 0 0
0 0 0 0 1
0 0 0 4 0"/>
<feColorMatrix in="SourceGraphic" result="opaque-source" type="matrix"
values ="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 4 0"/>
<feComposite operator="atop" in="solid-blue" in2="opaque-source"/>
</filter>
</defs>
<g filter="url(#overlappy)" fill="none" stroke="red" stroke-width="4" stroke-opacity="0.5">
<path d="M187 240 L188 240 L315 217" />
<path d="M188 240 L315 217 L317 217" />
<path d="M315 217 L317 217 L330 306" />
<path d="M317 217 L330 306 L247 233"/>
<path d="M330 306 L247 233 L258 226" />
<path d="M247 233 L258 226 L292 222" />
<path d="M258 226 L292 222 L303 178" />
<path d="M292 222 L303 178 L353 165" />
<path d="M303 178 L353 165" />
</g>
</svg>
Upvotes: 0
Reputation: 101830
Messing with opacity won't help as the path is rendered in one pass and it doesn't matter how many times it overlaps itself. All that matters is whether the pixel is considered "inside" the path stroke, or not. If it is, it is given the final line colour and opacity.
There is basically no good simple solution to your problem as far as I can see. The closest you can get is to draw all of the individual line segment individually. That way your opacity trick will highlight the overlaps (use stroke-opacity
rather than opacity
), but the joins between the line segments won't look very good. They'll have gaps, and you will see the overlap effects there as well.
<svg width="500" height="500" fill="none" stroke-opacity="0.6" stroke-width="14" stroke = "red">
<path d="M187 240 L188 240" />
<path d="M188 240 L315 217" />
<path d="M315 217 L317 217" />
<path d="M317 217 L330 306" />
<path d="M330 306 L247 233" />
<path d="M247 233 L258 226" />
<path d="M258 226 L292 222" />
<path d="M292 222 L303 178" />
<path d="M303 178 L353 165" />
</svg>
The only good solution would be to determine the overlap mathematically and then generate "overlap polygons" of the correct shape. That is a rather tricky bit of code.
Upvotes: 4