Search code examples
svgsvg-filters

Why is this SVG drop shadow filter clipping the path when it's short?


So I need some help understanding what's happening with this SVG.

When the path is short and I apply a filter for a drop shadow I get some weird clipping. It doesn't happen when the path is longer.

Short path, with shadow (broken)

Short path, with shadow

Short path, no shadow

Short path, no shadow

Longer path, with shadow

Longer path, with shadow

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
  <g transform="translate(125,125)">
    <filter id="dropshadow" x="-125" y="-125" width="250" height="250">
      <feGaussianBlur in="SourceAlpha" stdDeviation="3"></feGaussianBlur>
      <feOffset dx="2" dy="2" result="offsetblur"></feOffset>
      <feComponentTransfer>
        <feFuncA type="linear" slope="0.5"></feFuncA>
      </feComponentTransfer>
      <feMerge>
        <feMergeNode></feMergeNode>
        <feMergeNode in="SourceGraphic"></feMergeNode>
      </feMerge>
    </filter>
    <circle
      cx="0"
      cy="0"
      r="58.5"
      stroke="#BBE4D1"
      stroke-width="7px"
      fill="none"
    ></circle>
    <path
      d="M 1.3612572924182083 -64.98574442586495 A 65 65 0 0 0 3.980102097228898e-15 -65"
      stroke="#28B681"
      stroke-width="20px"
      fill="none"
      stroke-linecap="round"
      style="filter: url('#dropshadow')"
    ></path>
    <circle
      cx="0"
      cy="0"
      r="55"
      fill="white"
      style="filter: url('#dropshadow')"
    ></circle>
  </g>
</svg>

Plunker here: link


Solution

    • The default filterUnits is objectBoundingBox

    • Since you've not specified filterUnits that's what you'll get

    • objectBoundingBox units run from 0 to 1, you might use slightly larger values if your filter goes outside the shape but numbers in the hundreds are clearly a mistake.

    • I've corrected your testcase by explicitly specifying the more appropriate userSpaceOnUse units that the values would seem to warrant.

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 250">
      <g transform="translate(125,125)">
        <filter id="dropshadow" x="-125" y="-125" width="250" height="250" filterUnits="userSpaceOnUse">
          <feGaussianBlur in="SourceAlpha" stdDeviation="3"></feGaussianBlur>
          <feOffset dx="2" dy="2" result="offsetblur"></feOffset>
          <feComponentTransfer>
            <feFuncA type="linear" slope="0.5"></feFuncA>
          </feComponentTransfer>
          <feMerge>
            <feMergeNode></feMergeNode>
            <feMergeNode in="SourceGraphic"></feMergeNode>
          </feMerge>
        </filter>
        <circle
          cx="0"
          cy="0"
          r="58.5"
          stroke="#BBE4D1"
          stroke-width="7px"
          fill="none"
        ></circle>
        <path
          d="M 1.3612572924182083 -64.98574442586495 A 65 65 0 0 0 3.980102097228898e-15 -65"
          stroke="#28B681"
          stroke-width="20px"
          fill="none"
          stroke-linecap="round"
          style="filter: url('#dropshadow')"
        ></path>
        <circle
          cx="0"
          cy="0"
          r="55"
          fill="white"
          style="filter: url('#dropshadow')"
        ></circle>
      </g>
    </svg>