Create an SVG circle's drop shadow without the circle itself

Viewed 746

I want to create the shadow of an circle, while leaving the centre of the circle transparent.

circle shadow

I can't work out how to do it. I've tried using masks and filters, but they seem to cancel each other out. The mask cuts off the filter.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
  width="200" height="200" viewBox="0 0 200 200" >
  <defs>
    <filter id="blur">
      <feDropShadow dx="0" dy="0" stdDeviation="4.5"
          flood-color="black"/>
    </filter>
    <mask id="circle-mask" x="0" y="0" width="1" height="1">  
      <circle cx="75" cy="75" r="50" />  
    </mask>
  </defs>
  <circle cx="75" cy="75" r="50" style="mask: url(#circle-mask) filter: url(#blur)"/>
</svg>

I've tried used a circle as a clipPath, but that clips everything outside the circle (I want to clip the inside). I've tried messing the groups, putting the mask on the group and the filter on the circle (and the other way round). I've tried putting the mask and the filter into a style.

I'm not getting anywhere. How do I make the inside of the circle transparent?

2 Answers

You can do this in a compact way by extending your filter. The additional feComposite/out will remove anything that overlaps with the original shape (assuming your shape is always fully opaque).

body {
background: grey;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
  width="200" height="200" viewBox="0 0 200 200" >
  <defs>
    <filter id="blur-out">
      <feDropShadow dx="0" dy="0" stdDeviation="4.5"
          flood-color="black"/>
      <feComposite operator="out" in2="SourceGraphic"/>
    </filter>
  </defs>
  <circle cx="75" cy="75" r="50" filter= "url(#blur-out)"/>
</svg>

Just make the mask bigger. You'll need to make the bits you don't want to mask white and the bits you do black.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
  width="200" height="200" viewBox="0 0 200 200" >
  <defs>
    <filter id="blur">
      <feDropShadow dx="0" dy="0" stdDeviation="4.5"
          flood-color="black"/>
    </filter>
    <mask id="circle-mask" x="-0.2" y="-0.2" width="1.4" height="1.4">
      <rect width="100%" height="100%" fill="white"/>
      <circle cx="75" cy="75" r="50" fill="black"/>  
    </mask>
  </defs>
  <circle cx="75" cy="75" r="50" style="mask: url(#circle-mask); filter: url(#blur)"/>
</svg>

Related