Search code examples
svgsvg-filters

SVG filter parameters


Let's say I have an svg filter that applies a drop shadow to an element:

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<filter id="dropShadow">
  <feFlood result="flood" flood-color="#000" flood-opacity="0.6" />
  <feComposite in="flood" in2="SourceGraphic" operator="in" result="mask" />
  <feGaussianBlur in="mask" stdDeviation="0.3" result="shadow" />
  <feOffset in="shadow" dx="-1" dy="1" result="drop-shadow" />
  <feMerge>
    <feMergeNode in="drop-shadow"/>
    <feMergeNode in="SourceGraphic"/>
  </feMerge>
</filter>
<circle r="40" cx="50" cy="50" fill="#F00" filter="url(#dropShadow)" />
</svg>

This works fine and dandy - but what happens when I want to have different types of drop shadows in the same file? I end up with 5 copies of the same filter with only the color, opacity, offset and blur changed.

<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<filter id="dropShadow">
  <feFlood result="flood" flood-color="#000" flood-opacity="0.6" />
  <feComposite in="flood" in2="SourceGraphic" operator="in" result="mask" />
  <feGaussianBlur in="mask" stdDeviation="0.3" result="shadow" />
  <feOffset in="shadow" dx="-1" dy="1" result="drop-shadow" />
  <feMerge>
    <feMergeNode in="drop-shadow"/>
    <feMergeNode in="SourceGraphic"/>
  </feMerge>
</filter>
<filter id="dropShadow2">
  <feFlood result="flood" flood-color="#0F0" flood-opacity="1" />
  <feComposite in="flood" in2="SourceGraphic" operator="in" result="mask" />
  <feGaussianBlur in="mask" stdDeviation="1" result="shadow" />
  <feOffset in="shadow" dx="-1" dy="1" result="drop-shadow" />
  <feMerge>
    <feMergeNode in="drop-shadow"/>
    <feMergeNode in="SourceGraphic"/>
  </feMerge>
</filter>
<filter id="dropShadow3">
  <feFlood result="flood" flood-color="#000" flood-opacity="0.6" />
  <feComposite in="flood" in2="SourceGraphic" operator="in" result="mask" />
  <feGaussianBlur in="mask" stdDeviation="0.1" result="shadow" />
  <feOffset in="shadow" dx="2" dy="2" result="drop-shadow" />
  <feMerge>
    <feMergeNode in="drop-shadow"/>
    <feMergeNode in="SourceGraphic"/>
  </feMerge>
</filter>
<filter id="dropShadow4">
  <feFlood result="flood" flood-color="#F00" flood-opacity="0.6" />
  <feComposite in="flood" in2="SourceGraphic" operator="in" result="mask" />
  <feGaussianBlur in="mask" stdDeviation="1" result="shadow" />
  <feOffset in="shadow" dx="0" dy="0" result="drop-shadow" />
  <feMerge>
    <feMergeNode in="drop-shadow"/>
    <feMergeNode in="SourceGraphic"/>
  </feMerge>
</filter>
<circle r="10" cx="30" cy="30" fill="#F00" filter="url(#dropShadow)" />
<circle r="10" cx="30" cy="70" fill="#F00" filter="url(#dropShadow2)" />
<circle r="10" cx="70" cy="70" fill="#F00" filter="url(#dropShadow3)" />
<circle r="10" cx="70" cy="30" fill="#F00" filter="url(#dropShadow4)" />
</svg>

Not dry at all...

Is there any way to pass parameters to filters for code reuse?


Solution

  • There is no way to pass a parameter to an SVG Filter. There is a provision in the SVG 1.1 spec to allow a filter to incorporate nodes from another filter by using an xlink:href to that foreign filter in the filter element (but the referencing filter must have no primitives itself) - and (thank you Robert Longson) Firefox supports this feature but IE and Chrome do not.