Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SVG: Multiple Effects in One Filter

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!

like image 916
Nick Budden Avatar asked Mar 31 '14 07:03

Nick Budden


People also ask

Can svgs have drop shadows?

The SVG <feDropShadow> filter primitive creates a drop shadow of the input image. It can only be used inside a <filter> element. Note: The drop shadow color and opacity can be changed by using the flood-color and flood-opacity presentation attributes.

How to use SVG filter in CSS?

To use an SVG filter in CSS, use the url keyword, define a URI that defines an SVG file, and reference a filter with an id . That's it! The waves filter you see above is a modified version of the presets included at yoksel.github.io/svg-filters/. The waves effect shows the power of SVG filters.

How do SVG filters work?

SVG is an open-standard XML format for two-dimensional vector graphics as defined by the World Wide Web Consortium (W3C). A filter effect consists of a series of graphics operations that are applied to a given source vector graphic to produce a modified bitmapped result. Filter effects are defined by filter elements.

Can I use SVG filters?

Applying SVG Filters To HTML Content #SVG filters on HTML content are currently supported in WebKit, Firefox and Blink. IE and Microsoft Edge will display the unfiltered element, so make sure that the default look is good enough. The SVG that contains the filter may not be set to display: none .


2 Answers

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.

like image 53
Erik Dahlström Avatar answered Sep 28 '22 08:09

Erik Dahlström


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/

like image 31
karly Avatar answered Sep 28 '22 08:09

karly