svggradientsvg-filters

SVG Contoured Stroke Gradients?


I was doing some SVG banners for my website, and I was wondering: Is it possible to use gradients to make the stroke mimic the pixel art in the following image?

An old banner with pixel art going from yellow to red, contoured around the letters

I used pixel art here to make an outline of each letter going from red through orange, to yellow, and I was wondering if SVG has this capability, or some other way to mimic the results.


Solution

  • Here's how you would do a feMorphology based filter to get that effect

    body {
      background-color: black;
    }
    <svg width="800px" height="600px">
      <defs>
    <filter id="colorize" color-interpolation-filters="sRGB">
      <feMorphology operator="dilate" radius="1"/>
      <feColorMatrix result="yellow" type="matrix" values="1 0 0 0 0 
                                           0 1 0 0 0
                                           0 0 0 0 0 
                                           0 0 0 1 0"/>
        <feMorphology operator="dilate" radius="1"/>
      <feColorMatrix result="orange" type="matrix" values="1 0 0 0 0 
                                           0 0.6 0 0 0
                                           0 0 0 0 0 
                                           0 0 0 1 0"/>
      <feMorphology operator="dilate" radius="1"/>
      <feColorMatrix result="red" type="matrix" values="1 0 0 0 0 
                                           0 0 0 0 0
                                           0 0 0 0 0 
                                           0 0 0 1 0"/>
      <feFlood flood-color="black"/>
      <feComposite result="black" operator="in" in2="SourceGraphic"/>
      
        <feMerge>
            <feMergeNode in= "red"/>
            <feMergeNode in= "orange"/>    
            <feMergeNode in= "yellow"/>
        <feMergeNode in="black"/>
       </feMerge>
      </filter>
        
      </defs>
    
    <g filter="url(#colorize)">
      <text x="50" y="50" style="font-size:60px" fill="white">Sample Text</text>
      </g>
    </svg>

    If you want to make your base text more pixelated, you can remove text anti-aliasing using a feComponentTransfer on the alpha channel. Add more 0's to the start of the feFuncA tableValues array for a crispier effect - it will convert more of the anti-aliased edge to fully transparent.

    body {
      background-color: black;
    }
    <svg width="800px" height="600px">
      <defs>
    <filter id="colorize" color-interpolation-filters="sRGB">
      <feComponentTransfer result="crispyText">
        <feFuncA type="discrete" tableValues="0 0 0 1"/>
      </feComponentTransfer>
      
      <feMorphology operator="dilate" radius="1"/>
      <feColorMatrix result="yellow" type="matrix" values="1 0 0 0 0 
                                           0 1 0 0 0
                                           0 0 0 0 0 
                                           0 0 0 1 0"/>
        <feMorphology operator="dilate" radius="1"/>
      <feColorMatrix result="orange" type="matrix" values="1 0 0 0 0 
                                           0 0.6 0 0 0
                                           0 0 0 0 0 
                                           0 0 0 1 0"/>
      <feMorphology operator="dilate" radius="1"/>
      <feColorMatrix result="red" type="matrix" values="1 0 0 0 0 
                                           0 0 0 0 0
                                           0 0 0 0 0 
                                           0 0 0 1 0"/>
      <feFlood flood-color="black"/>
      <feComposite result="black" operator="in" in2="crispyText"/>
      
        <feMerge>
            <feMergeNode in= "red"/>
            <feMergeNode in= "orange"/>    
            <feMergeNode in= "yellow"/>
        <feMergeNode in="black"/>
       </feMerge>
      </filter>
        
      </defs>
    
    <g filter="url(#colorize)">
      <text x="50" y="50" style="font-size:60px" fill="white">Sample Text</text>
      </g>
    </svg>