1

If I were to create a simple inline svg, I could modify paths to have a drop shadow or a blur by creating a <filter> within a <defs> grouping. However, Leaflet dynamically generates the SVGs it uses to display paths, and I'm not sure how to add a filter after the fact.

Failed Ideas:

  • I've tried using jQuery to append a defs to the SVG after the fact:

Like this:

    $("svg").prepend("<defs><filter id='dropshadow' height='130%'><feGaussianBlur in='SourceAlpha' stdDeviation='3'/> <!-- stdDeviation is how much to blur --> <feOffset dx='2' dy='2' result='offsetblur'/> <!-- how much to offset --><feMerge><feMergeNode/> <!-- this contains the offset blurred image --><feMergeNode in='SourceGraphic'/> <!-- this contains the element that the filter is applied to --></feMerge></filter></defs>");

And then specify the location of the defs in my CSS, like this:

    filter: url("../index.html#dropshadow");
  • Have the <defs> / filter definition already inline in the html above the map element, and then reference the filter definition from the svg via a the CSS filter URL.

My code (inline above the leaflet map div):

    <svg xmlns="w3.org/2000/svg"; version="1.1">
        <defs>
            <filter id='dropshadow' height='130%'>
                <feGaussianBlur in='SourceAlpha' stdDeviation='3'/> <!-- stdDeviation is how much to blur --> 
                <feOffset dx='2' dy='2' result='offsetblur'/> <!-- how much to offset -->
                <feMerge><feMergeNode/> <!-- this contains the offset blurred image -->
                <feMergeNode in='SourceGraphic'/> <!-- this contains the element that the filter is applied to --></feMerge>
            </filter>
        </defs>
    </svg>
3

I'd suggest going with your second approach of putting your svg markup in-line. I think your jQuery prepend method doesn't work because you need to create <defs> and other children of <svg> elements using document.createElementNS and jQuery is probably using document.createElement.

Anyway, the piece you're missing is applying your filter to your svg, which you could do two ways.

CSS approach:

div.leaflet-overlay-pane svg > g path {
  filter: url(#dropshadow);
}

$ approach (put this after you add your geojson to your map):

$("div.leaflet-overlay-pane svg > g path").css({
  filter: "url(#dropshadow)"
}); 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.