Question

I have an SVG where I'm using filters to blend white shapes on top of black backgrounds using multiply blending. Since I'm using multiply, I would expect the white shape not to show up at all, but this is not the case. In this example I'm drawing a square in its own filter, then a smaller circle (also in its own filter):

http://jsfiddle.net/mugwhump/SwcjL/2/

However, there is a faint, pixel-wide white outline surrounding the circle. The color and opacity of this outline depends on the color and opacity used to draw the circle.

It disappears if I move the circle into the same filter group as the square, but unfortunately that's not an option.

Any idea how to get rid of that outline? This happens in basically all browsers/renderers.

Here's the code for the svg:

<svg contentScriptType="text/ecmascript" width="530"
 xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"
 contentStyleType="text/css" viewBox="0 0 530 530" height="530"
 preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg"
 version="1.1">

<defs id="defs">
    <!--Blend using multiply. -->
    <filter color-interpolation-filters="sRGB" x="-1.0" y="-1.0" width="3.0"
        xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple"
        xlink:actuate="onLoad" height="3.0" 
        xlink:show="other" id="blend-square-multiply">
        <feFlood result="blackness" flood-color="black"/>
        <feComposite result="blackness clip" in="blackness" in2="SourceGraphic" operator="in"/>
        <feColorMatrix in="SourceGraphic" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0" type="matrix" result="color-trans"/>
        <feBlend mode="multiply" in="blackness clip" in2="color-trans"/>
    </filter>
</defs>

<!-- White square blended with multiply over black feFlood -->
<g filter="url(#blend-square-multiply)">
    <g fill="white" >
        <rect  x="200" width="100" y="200" height="100" />
    </g>
</g>
<!-- White circle blended with multiply over black feFlood 
Changing stroke width does nothing, but changing fill color changes
the color of the outline (changing stroke-color does not). 
The outline disappears when opacity is set to 0. -->
<g filter="url(#blend-square-multiply)">
    <g fill="white" opacity="1">
        <circle stroke-width="0" cx="250" cy="250" r="50"/>
    </g>
</g>

Was it helpful?

Solution

Remember that source graphics are rasterized before they're handed to the filter pipeline and hence shed their vectorish nature when they enter the threshold of filterdom.

You are getting that effect because the circle element has an edge of anti-aliasing aka semi-opaque pixels around its edges. When those are multiplied with black, you get grey.

Use shape-rendering="crispEdges" to avoid this. Or use an feMorphology erode filter to clip the edges of the antialiasing. Or use an feFuncA filter to dial those edges up to full opacity first. On second thought -- that first idea.

<circle shape-rendering="crispEdges" stroke-width="0" cx="250" cy="250" r="50"/>

OTHER TIPS

I think the enable-background attribute may be the answer to your problem.

http://www.w3.org/TR/SVG/filters.html#EnableBackgroundProperty

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top