I am applying <feFlood>
to a svg Element. However, upon applying, the stroke and stoke-width are getting negatively affected by that.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 600">
<defs>
<filter id="filt">
<feFlood x="100" y="100" height="200" width="300" flood-color="red" flood-opacity=".5"></feFlood>
</filter>
</defs>
<rect class="bg" x="0" y="0" width="1280" height="600" fill="#EFEFEF"></rect>
<rect class="elementRect" x="100" y="100" width="300" height="200" stroke="black" stroke-width="5" filter="url(#filt)"></rect>
</svg>
How can I have the filter affecting only the fill of elementRect
and not the stroke
?
You can do it all in a filter by using a green-screen technique. Start by coloring the fill red and the stroke blue in the content, then use two color matrices to separate them out into separate layers, color them and then recombine them.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 600" color-interpolation-filters="sRGB">
<defs>
<filter id="filt" >
<feFlood x="100" y="100" height="200" width="300" flood-color="red" flood-opacity=".5" result="fill-content"></feFlood>
<feFlood x="100" y="100" height="200" width="300" flood-color="black" flood-opacity="1" result="stroke-content"></feFlood>
<feColorMatrix in="SourceGraphic" result="fill-clip" type="matrix" values="0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
-1 0 0 1 0"/>
<feColorMatrix in="SourceGraphic" result="stroke-clip" type="matrix" values="0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
0 0 -1 1 0"/>
<feComposite operator="in" in="fill-content" in2="fill-clip" result="just-fill"/>
<feComposite operator="in" in="stroke-content" in2="stroke-clip" result="just-stroke"/>
<feComposite operator="over" in2="just-fill" in="just-stroke"/>
</filter>
</defs>
<rect class="bg" x="0" y="0" width="1280" height="600" fill="#EFEFEF"></rect>
<rect class="elementRect" x="100" y="100" width="300" height="200" stroke="red" fill="blue" stroke-width="5" filter="url(#filt)"></rect>
</svg>
Update: If you want to replace the fill with turbulence, then you still want to select out the stroke first into a new layer, then do whatever you want with the fill, then add back the stroke. There is no way in a filter to distinguish the stroke from the fill (there was supposed to be one, but it was never implemented) - you have to color them differently so the filter can distinguish between them based on their color.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 600" color-interpolation-filters="sRGB">
<defs>
<filter id="filt" x="0%" y="0%" width="100%" height="100%">
<feFlood x="100" y="100" height="200" width="300" flood-color="black" flood-opacity="1" result="stroke-content"></feFlood>
<feColorMatrix in="SourceGraphic" result="stroke-clip" type="matrix" values="0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
0 0 -1 1 0"/>
<feComposite operator="in" in="stroke-content" in2="stroke-clip" result="just-stroke"/>
<feColorMatrix in="SourceGraphic" result="fill-clip" type="matrix" values="0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
-1 0 0 1 0"/>
<feTurbulence type="fractalNoise" baseFrequency="0.1" numOctaves="3"/>
<feComposite operator="over" in="just-stroke"/>
</filter>
</defs>
<rect class="bg" x="0" y="0" width="1280" height="600" fill="#EFEFEF"></rect>
<rect class="elementRect" x="100" y="100" width="300" height="200" stroke="red" fill="blue" stroke-width="5" filter="url(#filt)"></rect>
</svg>