Search code examples
svgsvg-filters

Apply SVG lighting filter to path only


I'm trying to create a a metallic effect on a path in an SVG using a lighting filter. My initial attempt seems to lighting the whole bounding box of the path rather than just the stroke.

Is there a way to restrict the filter's effect to just the stroke?

This is the code I currently have...

<svg
  xmlns="http://www.w3.org/2000/svg"
  width="220"
  height="220"
  fill="none"
  viewBox="0 0 220 220"
>
  <filter id="filter">
    <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur1" />
    <feSpecularLighting
      result="specOut"
      in="blur1"
      specularExponent="40"
      lighting-color="#48d913"
    >
      <fePointLight x="50" y="100" z="200" />
    </feSpecularLighting>
    <feComposite
      in="SourceGraphic"
      in2="specOut"
      operator="arithmetic"
      k1="0"
      k2="1"
      k3="1"
      k4="0"
    />
  </filter>
  <g className="15-american-oak">
    <path
      stroke="#A32226"
      strokeMiterlimit="10"
      strokeWidth="1.22"
      d="M156.97 175.88c-24.23 0-43.95-19.72-43.95-43.95 0-24.23 19.72-43.95 43.95-43.95"
      style="filter: url(#filter)"
    />
  </g>
</svg>

And this is what the current output looks like...

enter image description here


Solution

  • You can use a second composite operation to keep only the parts that are within the path:

    <feComposite
      in="SourceGraphic"
      in2="specOut"
      operator="arithmetic"
      result="comp"
      k1="0"
      k2="1"
      k3="1"
      k4="0"
    />
    <feComposite 
      in="comp"
      in2="SourceAlpha"
      operator="in"
    />