Here is a complete solution that works in both browsers I tested (Firefox and Chrome)...
Solution for Question 1: None of the browsers I tested support specifying more than one filter in the filter property, so the best (and perhaps only) way to combine user-defined filters is using the technique suggested by Michael Mullany: apply them sequentially in nested <g>
elements, creating the filter graph as desired.
Solution for Question 2: The W3C has a working draft for SVG Parameters and the draft includes a polyfill script for using and testing the proposed feature. Parameters are declared via param()
functional attribute value (e.g., param(shadowColor) black
) and defined through a query-string-like interface (e.g., foo.svg?shadowColor=red
) or through child elements of the <object>
container (e.g., <param name="shadowColor" value="red"/>
).
Demo code for both solutions is provided below, along with a screenshot from Firefox.
in mypage.html:
<object type="image/svg+xml" data="filters.svg?osColor=lime&dsAlpha=0.4"></object>
<object type="image/svg+xml" data="filters.svg?osColor=white&osWidth=4&dsAlpha=0.8&dsBlurSigma=8&dsOffsetX=32"></object>
in filters.svg:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="300px" height="320px" viewBox="0 0 300 320">
<defs>
<filter id="dropShadow" width="150%">
<feGaussianBlur in="SourceAlpha" stdDeviation="param(dsBlurSigma) 4" />
<feOffset result="m_offsetBlurred" dx="param(dsOffsetX) 12" dy="param(dsOffsetY) 12" />
<feComponentTransfer result="m_offsetBlurredTranslucent" in="m_offsetBlurred">
<feFuncA type="linear" slope="param(dsAlpha) 0.5" />
</feComponentTransfer>
<feMerge>
<feMergeNode in="m_offsetBlurredTranslucent" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<filter id="outerStroke" width="150%">
<feFlood result="m_floodRect" flood-color="param(osColor) black" />
<feMorphology result="m_expandedMask" in="SourceAlpha" operator="dilate" radius="param(osWidth) 1" />
<feComposite result="m_expandedColored" in="m_floodRect" in2="m_expandedMask" operator="in" />
<feBlend in="SourceGraphic" in2="m_expandedColored" mode="normal" />
</filter>
</defs>
<!-- combine stroke & drop shadow -->
<g style='filter:url(#dropShadow);' width='300' height='320'>
<g style='filter:url(#outerStroke);'>
<image width='240' height='280' xlink:href="gfx/odd_shape.png"></image>
</g>
</g>
<!-- use polyfill from http://dev.w3.org/SVG/modules/param/master/SVGParamPrimer.html -->
<script type="text/ecmascript" xlink:href="http://dev.w3.org/SVG/modules/param/master/param.js" />
</svg>
The result: