Search code examples
jqueryhtmlcsssvggsap

Where a low quality SVG mask shows jagged edges, is there any way to fix using anti-aliasing?


I made a SVG mask animation. The problem I am having is the edges of the SVG are "jagged" I can see a slight black edge around the mask when the animation comes in. (It's very slight. I have seen animated GIFs with better quality. Using an SVG I thought it would be cleaner).

Looking for a solution for softer edges. If that means I need to use PNG mask or apply some type of filter effects? I'd be happy for any solution.

CODEPEN

<mask id="text-mask">
<use x="0" y="0" xlink:href="#text" opacity="1" fill="#fff"/>
</mask>

<use x="0" y="0" xlink:href="#text" fill="#0d0d0d"/>

<rect class="water-fill" mask="url(#text-mask)" fill="url(#water)" x="-400"     y="0" width="6000" height="650"/>

Solution

  • The reason you are seeing that "jagged edge" dark outline is due to the way you've done your SVG. You are stacking two copies of the black text path on top of themselves. Then you are putting the red water animation on top of those.

    Your SVG looks like this:

    <svg>
       <path with QURE (black)>
       <use that path again (black)>
       <water animation (red) using that path as a mask>
    </svg>
    

    You have three antialiased elements stacked directly on top of one another. Two of them black and one of them red. So on the edges of the shapes you are getting a mix of black and red semi-transparent pixels.

    You can improve the look a lot by putting that first <path> definition in a <defs> section so it doesn't get rendered.

    That leaves you with this arrangement:

    <svg>
       <use path with QURE shape (black)>
       <water animation (red) using that path as a mask>
    </svg>
    

    That helps, but still leaves a mix of black and red pixels on the edge of the shapes. You can improve the look even more by not drawing the black text behind the red animation.

    The best results will be achieved by having the following sort of arrangement:

    <svg>
      <g with QURE mask>
        <black rectangle background>
        <water animation (red)>
      </g>
    </svg>
    

    With this arrangement we are applying the mask only once to the combined black and red water animation. So you should get no black jaggy border because there is now only one set of anti-alias pixels.

    Demo codepen with these changes applied.