I am studying some basic image manipulations with SVG and trying to find optimal approach for the following challenge:
We have one SVG file which has various SVG elements (circles, rectangle, triangle). They all are overlapping each other creating new "areas" of different forms (see pic).
So filling actual Elements - no problem there. But what if I want to fill with color only specific intersect area?
My current thinking was:
Michael's filter method is cool and tricky, but perhaps a little hard to understand.
You can also do it with masks.
<svg width="391" height="400">
<defs>
<!-- define the shapes in the image, which we will use for the outlines
and for creating intersection masks -->
<rect id="square" x="92" y="48" width="218" height="218"/>
<polygon id="triangle" points="54,366 277,366 165,142"/>
<circle id="circle" cx="256" cy="264" r="85"/>
<!-- the masks -->
<!-- white parts are visible, black parts are invisible -->
<mask id="square-minus-triangle">
<!-- square with triangle cut out of it -->
<use xlink:href="#square" fill="white"/>
<use xlink:href="#triangle" fill="black"/>
</mask>
<mask id="triangle-minus-square">
<!-- triangle with square cut out of it -->
<use xlink:href="#triangle" fill="white"/>
<use xlink:href="#square" fill="black"/>
</mask>
</defs>
<!-- background -->
<rect width="100%" height="100%" fill="#e5e4da"/>
<!-- the intersection shapes (yellow) -->
<!-- first draw the circle, but use the square-minus-triangle mask.-->
<use xlink:href="#circle" fill="#e4e400" mask="url(#square-minus-triangle)"/>
<!-- draw the circle again, but use the triangle-minus-square mask.-->
<use xlink:href="#circle" fill="#e4e400" mask="url(#triangle-minus-square)"/>
<!-- draw the outlined shapes -->
<g fill="none" stroke="black" stroke-width="6">
<use xlink:href="#square"/>
<use xlink:href="#triangle"/>
<use xlink:href="#circle"/>
</g>
</svg>
You can do this with filters. An easy way to do is to use near transparent fill and then use a filter to dial the non-overlapping areas to fully transparent and the overlapping areas to fully opaque. It makes the stroke a little crispy though.
<svg height="600px" width="800px">
<defs>
<filter id="opacitychange">
<feComponentTransfer>
<feFuncA type="linear" intercept="-.05"/>
</feComponentTransfer>
<feComponentTransfer>
<feFuncA type="gamma" amplitude="4" exponent=".4"/>
</feComponentTransfer>
</filter>
</defs>
<g filter="url(#opacitychange)">
<circle stroke="black" fill="blue" fill-opacity="0.05" cx="150" cy="150" r="100"/>
<rect stroke="black" x="200" y="100" width="100" height="300" fill="blue" fill-opacity="0.05"/>
<polygon stroke="black" points="50,50 50,400 300,400" fill="blue" fill-opacity="0.05"/>
</g>
</svg>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With