Question

I'm trying to implement multiple drop shadows into a single SVG filter, but I believe my question is more generic than that: how can I add multiple effects into a single SVG filter? In my case, here's specifically what I'm trying to do.

I've got an SVG document that currently contains a single path element, and I've applied a single drop shadow effect to this path element.

My SVG Document

 <svg xmlns:xlink="http://www.w3.org/1999/xlink" width="1440" height="1750">
      <defs>
        <filter id="dropshadow">
          <feGaussianBlur in="SourceAlpha" stdDeviation="2.2"></feGaussianBlur>
          <feOffset dx="12" dy="12" result="offsetblur"></feOffset>
          <feFlood flood-color="rgba(0,0,0,0.5)"></feFlood>
          <feComposite in2="offsetblur" operator="in"></feComposite>
          <feMerge>
            <feMergeNode></feMergeNode>
            <feMergeNode in="SourceGraphic"></feMergeNode>
          </feMerge>
        </filter>
      </defs>

      <path xmlns:xlink="http://www.w3.org/1999/xlink" d="M 100 100 L 300 100 L 200 300 z z" fill="#2DA9D6" filter="url(#dropshadow)"></path>
    </svg>

Which gives me an SVG that looks like this:

enter image description here

Now, I want to add a second (completely different) drop shadow to this same path element. For example, let's say a drop shadow that goes up and to the left of the element. In CSS my whole dropshadow might look like:

box-shadow: 5px 5px 5px rgba(0,0,0,0.5), -5px -5px 5px rgba(0,0,0,0.5);

How can I do these multiple shadows with SVG filters? I've had a look at this question which suggests putting multiple effects into one filter, but I'm not sure how to merge multiple effects into one filter.

Thanks for any help!

Was it helpful?

Solution

You can use the result attributes to give a name to a filter primitive element's output, think of it as a sort of filter-local id attribute. You can then use that name as filter input with the in or in2 attributes.

<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="1440" height="1750">
  <defs>
    <filter id="dropshadow">
     <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/> 
      <feOffset dx="12" dy="12" result="offsetblur"/>
      <feOffset dx="-20" dy="-12" result="offsetblur2" in="blur"/>
      <feComponentTransfer result="shadow1" in="offsetblur">
        <feFuncA type="linear" slope="0.5"/>
      </feComponentTransfer>
      <feComponentTransfer result="shadow2" in="offsetblur2">
        <feFuncA type="linear" slope="0.2"/>
      </feComponentTransfer>
      <feMerge> 
        <feMergeNode in="shadow1"/>
        <feMergeNode in="shadow2"/>
        <feMergeNode in="SourceGraphic"/> 
      </feMerge>
    </filter>
  </defs>

  <path xmlns:xlink="http://www.w3.org/1999/xlink" d="M 100 100 L 300 100 L 200 300 z z" fill="#2DA9D6" filter="url(#dropshadow)"></path>
</svg>

See fiddle.

OTHER TIPS

You can do multiple filters using just CSS! Use a function for each filter separated by a space:

.multiple-different-filters {
  filter: blur(20px) grayscale(20%);
}


.double-dropshadow {
  filter: drop-shadow(5px 5px 5px rgba(0,0,0,0.5)) drop-shadow(-5px -5px 5px rgba(0,0,0,0.5));

}

You need to call the drop-shadow() function for each shadow separately.

From: https://css-tricks.com/almanac/properties/f/filter/

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