I have a shape with a stroke. The fill is orange with 50% opacity (so alpha = .5 and rgb(255,112,0)) and the stroke is blue (no transparency).
Using filters, I've been trying to make a copy (similar to a drop shadow, but without the blur). I'd like the copy to be solid orange.
But I just can't seem to get this as feColorMatrix
continues to use SourceGraphic
values.
No idea why, but if my shape fill is no transparency, and I also use feComponentTransfer
again, I can get the solid shape copy.
The shape on the right is the one I'd like to make solid orange (or any color and opacity I choose), regardless of shape/stroke fill/opacity.
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="960" height="540" class="slide" shape-rendering="geometricPrecision" fill-rule="evenodd">
<rect width="960" height="540" stroke="#385D8A" fill="white" stroke-width="3" class="testSlideBorder" />
<svg x="10" y="10" overflow="visible" stroke="#0000FF" stroke-miterlimit="8" stroke-width="4">
<defs>
<filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
<feColorMatrix in="SourceAlpha" type="matrix" values="
0 0 0 0 1
0 0 0 0 0.439
0 0 0 0 0
0 0 0 1 0"
result="changeToOrangeFill"/>
<feComponentTransfer result="changedAgain">
<feFuncR type="linear" slope="1" />
<feFuncG type="linear" slope="0.439" />
<feFuncB type="linear" slope="0" />
<feFuncA type="linear" slope="1" />
</feComponentTransfer>
<feOffset dx="120"/>
</filter>
</defs>
<use xlink:href="#star" filter="url(#offsetColoredShape)" />
<path id="star" fill="rgb(255,112,0)" fill-opacity="0.5" d="M0,63.904L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z" />
</svg>
</svg>
Notice in the <path/>
that fill-opacity="0.5"
. If I change that to fill-opacity="1"
, it works as expected. Here's what that looks like:
<svg x="10" y="10" overflow="visible" fill="#4472C4" stroke="#0000FF" stroke-miterlimit="8" stroke-width="4">
<defs>
<filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
<feColorMatrix in="SourceAlpha" type="matrix" values="
0 0 0 0 1
0 0 0 0 0.439
0 0 0 0 0
0 0 0 1 0"
result="changeToOrangeFill"/>
<feComponentTransfer result="changedAgain">
<feFuncR type="linear" slope="1" />
<feFuncG type="linear" slope="0.439" />
<feFuncB type="linear" slope="0" />
<feFuncA type="linear" slope="1" />
</feComponentTransfer>
<feOffset dx="120"/>
</filter>
</defs>
<use xlink:href="#star" filter="url(#offsetColoredShape)" />
<path id="star" fill="rgb(255,112,0)" fill-opacity="1" d="M0,63.904L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z" />
</svg>
Any thoughts as to how I can get a solid color (like black) and alpha = 100% of the SourceGraphic
, and then be able to modify the color and it's opacity to any color/opacity I like?
You're not setting the alpha to 100% in your original feColorMatrix - you're multiplying the alpha by 1. If you want to set alpha to 100% - you should set the fifth column to 1 (not the fourth column).
Now the problem with that is that it sets all the background to 100% opacity as well so you get the rest of the graphic colored solid black.
But - we have a hack to get around this. Instead of using SourceAlpha - use SourceGraphic, and use the first three columns of the alpha row to boost the alpha of just the colored pixels to 100%. The result is a little crispy (because we nuke anti-aliasing) - but it does get you what you want and works for every color - including rgb(1,1,1).
If you know your colors are not going to be that close to black then, you can dial down those 255's to something more reasonable (like 5 or 10) & retain at least some of the anti-aliasing.
<svg x="10" y="10" overflow="visible" stroke="#0000FF" stroke-miterlimit="8" stroke-width="4" style="background:grey" color-interpolation-filters="sRGB">
<defs>
<filter id="offsetColoredShape" height="500%" width="500%" x="-275%" y="-275%">
<feColorMatrix in="SourceGraphic" type="matrix" values="
0 0 0 0 1
0 0 0 0 0.439
0 0 0 0 0
255 255 255 1 0"
result="changeToOrangeFill"/>
<feOffset dx="80"/>
</filter>
</defs>
<use xlink:href="#star" filter="url(#offsetColoredShape)" />
<path id="star" fill="rgb(255,112,0)" fill-opacity="0.5" d="M0,63.904L17.609,51.5L8.562,31.952L30.014,30.014L31.952,8.562L51.5,17.609L63.904,0L76.309,17.609L95.857,8.562L97.795,30.014L119.247,31.952L110.199,51.5L127.809,63.904L110.199,76.309L119.247,95.857L97.795,97.795L95.857,119.247L76.309,110.199L63.904,127.809L51.5,110.199L31.952,119.247L30.014,97.795L8.562,95.857L17.609,76.309Z" />
</svg>