4

I'm trying to create an svg which has a set of polylines, the polylines original coordinates are calculated elsewhere are they are relative to some other coordinate set, that's why I used svg's viewBox. I'm trying to apply the blur filter on the polylines and the filter seems to hide the polylines, tried a couple of filters, but nothing worked.

Here is a link to jsfiddle, you can see that the first polyline which has the filter applied is hidden and the other are shown.

   <svg viewBox="1427 337.6554260253906 33 307" height="307" width="33" >
     <filter id="blurMe2">
         <feGaussianBlur in="SourceGraphics" stdDeviation="5"/>
     </filter>
     <!--hidden-->
     <polyline points="1459,357 1459,643" style="stroke:#FCF4DD;stroke-width:1" filter="url(#blurMe2)"></polyline>
     <!--shown-->
     <polyline points="1456,358.1554395016353 1447,358.1554395016353" style="stroke:#FCF4DD;stroke-width:1" ></polyline>
     </svg>

Browser: Chrome Version 67.0.3396.87 (Official Build) (64-bit)

Anan
  • 113
  • 4
  • 1
    SourseGraphics is invalid. Correct your typo there and it should work. – Robert Longson Jun 19 '18 at 08:43
  • @Robert Longson It doesn't matter. Read `in` [specification](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/in). – JeB Jun 19 '18 at 10:38
  • 1
    @meltedspark MDN are no specs, the specs are [here](https://www.w3.org/TR/SVG11/filters.html#FilterPrimitiveInAttribute), and neither MDN article nor the specs say that it doesn't matter, quite at the contrary: (Not quoting) If the set value is neither of the six allowed keywords, then this value will be treated as "a previous ‘result’ attribute value within the same ‘filter’ element.". – Kaiido Jun 19 '18 at 10:44
  • @meltedspark not only have I read the SVG specification, [my name is on it](https://www.w3.org/TR/SVG11/) – Robert Longson Jun 19 '18 at 11:42
  • Unfortunately correcting the typo didn't help – Anan Jun 19 '18 at 12:39
  • @Robert Longson if you have some knowledge about specification and implementation of svg, maybe you can tell if there is an issue here in svg or is it by design? since if polyline I'm drawing has the same x/y coordinates in all it's points blur filter hides the polyline, just adding 1 to the x/y of one the points makes the visible again and the filter works. – Anan Jun 19 '18 at 15:05
  • @anan per https://www.w3.org/TR/SVG/coords.html#ObjectBoundingBoxUnits Keyword objectBoundingBox should not be used when the geometry of the applicable element has no width or no height – Robert Longson Jun 19 '18 at 15:24
  • @Kaiido All I'm trying to say is that in this particular case it doesn't matter. This is a first filter primitive, and the value of `in` is neither one of the six reserved words nor string which matches a previous `result` attribute within the same filter element (no `result` attribute at all). Therefore, quote: "If no value is provided and this is the first filter primitive, then this filter primitive will use *SourceGraphic* as its input". As you can [see](https://jsfiddle.net/s5hmwxv3/1/), the `in` value can be even *blahblah*, it will still work as *SourceGraphic*. – JeB Jun 19 '18 at 17:18
  • @RobertLongson So essentially my answer is correct isn't it? It won't work with two points (as the element has no width), while adding two more points will do the work. – JeB Jun 19 '18 at 17:21
  • 1
    @meltedspark If the typo problem is corrected, although you're filtering a different shape then. Better would be to correct the typo and convert it to use userSpaceOnUse units. – Robert Longson Jun 19 '18 at 17:28
  • 1
    Possible duplicate of [What is incorrect with this SVG document that uses feDropShadow?](https://stackoverflow.com/questions/47758565/what-is-incorrect-with-this-svg-document-that-uses-fedropshadow) – Michael Mullany Jun 20 '18 at 02:04
  • You cannot use default filter dimensioning when you're filtering a horizontal or vertical line - marked as duplicate of https://stackoverflow.com/questions/47758565/what-is-incorrect-with-this-svg-document-that-uses-fedropshadow – Michael Mullany Jun 20 '18 at 02:05
  • @RobertLongson thanks, I added it to my answer – JeB Jun 20 '18 at 08:11
  • Thank you very much guys, accepted @meltedspark 's answer since it fixed the problem – Anan Jun 20 '18 at 10:40

1 Answers1

2

The filter you defined won't work with polylines that consist of less than 3 points (as they don't have width).
You can workaround it by defining your polyline with 4 points:

<polyline points="1459,357 1459,643 1470,357 1470,643" style="stroke:#FCF4DD;stroke-width:1" filter="url(#blurMe2)"></polyline>

Working example:

<!DOCTYPE html>
<html>
<body style="background-color:red">

<svg viewBox="1427 337.6554260253906 33 307" height="307" width="33" >
   <filter id="blurMe2">
      <feGaussianBlur in="SourceGraphic" stdDeviation="2"/>
   </filter>
    
        <polyline points="1459,357 1459,643 1470,357 1470,643" style="stroke:#FCF4DD;stroke-width:1" filter="url(#blurMe2)"></polyline>
        
        <polyline _ngcontent-c6="" points="1456,358.1554395016353 1447,358.1554395016353" style="stroke:#FCF4DD;stroke-width:1" ></polyline>
        <polyline _ngcontent-c6="" points="1456,372.4398955514718 1453,372.4398955514718" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,386.7243516013083 1447,386.7243516013083" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,401.00880765114476 1453,401.00880765114476" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,415.2932637009812 1447,415.2932637009812" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,429.57771975081766 1453,429.57771975081766" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,443.86217580065414 1447,443.86217580065414" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,458.1466318504906 1453,458.1466318504906" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,472.4310879003271 1447,472.4310879003271" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,486.7155439501636 1453,486.7155439501636" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,501 1447,501" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,515.2844560498365 1453,515.2844560498365" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,529.568912099673 1447,529.568912099673" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,543.8533681495094 1453,543.8533681495094" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,558.1378241993459 1447,558.1378241993459" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,572.4222802491823 1453,572.4222802491823" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,586.7067362990189 1447,586.7067362990189" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,600.9911923488553 1453,600.9911923488553" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,615.2756483986918 1447,615.2756483986918" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,629.5601044485283 1453,629.5601044485283" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,643.8445604983647 1447,643.8445604983647" style="stroke:#FCF4DD;stroke-width:1"></polyline>
  </svg>
</body>
</html>

A proper solution though, as Robert Longson mentioned, is to use userSpaceOnUse as filterUnits.

Why? Because the real problem is that

If the filterUnits attribute isn't specified, then the effect is as if a value of objectBoundingBox were specified.

Which, in turn, is inapplicable to shapes without width:

Keyword objectBoundingBox should not be used when the geometry of the applicable element has no width or no height, such as the case of a horizontal or vertical line, even when the line has actual thickness when viewed due to having a non-zero stroke width since stroke width is ignored for bounding box calculations

Working example:

<!DOCTYPE html>
<html>
<body style="background-color:red">

<svg viewBox="1427 337.6554260253906 33 307" height="307" width="33" >
   <filter id="blurMe2" x="1427" y="337" filterUnits="userSpaceOnUse">
      <feGaussianBlur in="SourceGraphic" stdDeviation="2"/>
   </filter>
    
        <polyline points="1459,357 1459,643" style="stroke:#FCF4DD;stroke-width:2" filter="url(#blurMe2)"></polyline>
    
        <polyline _ngcontent-c6="" points="1456,358.1554395016353 1447,358.1554395016353" style="stroke:#FCF4DD;stroke-width:1" ></polyline>
        <polyline _ngcontent-c6="" points="1456,372.4398955514718 1453,372.4398955514718" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,386.7243516013083 1447,386.7243516013083" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,401.00880765114476 1453,401.00880765114476" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,415.2932637009812 1447,415.2932637009812" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,429.57771975081766 1453,429.57771975081766" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,443.86217580065414 1447,443.86217580065414" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,458.1466318504906 1453,458.1466318504906" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,472.4310879003271 1447,472.4310879003271" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,486.7155439501636 1453,486.7155439501636" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,501 1447,501" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,515.2844560498365 1453,515.2844560498365" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,529.568912099673 1447,529.568912099673" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,543.8533681495094 1453,543.8533681495094" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,558.1378241993459 1447,558.1378241993459" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,572.4222802491823 1453,572.4222802491823" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,586.7067362990189 1447,586.7067362990189" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,600.9911923488553 1453,600.9911923488553" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,615.2756483986918 1447,615.2756483986918" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,629.5601044485283 1453,629.5601044485283" style="stroke:#FCF4DD;stroke-width:1"></polyline>
        <polyline _ngcontent-c6="" points="1456,643.8445604983647 1447,643.8445604983647" style="stroke:#FCF4DD;stroke-width:1"></polyline>
  </svg>
</body>
</html>
JeB
  • 11,653
  • 10
  • 58
  • 87
  • why did you use 1459,357 1459,643 1470,357 1470,643 as coordinates x coordinate is suppose to be the same for all points 1459, when using 1459 it's still hidden. we need a straight vertical line. – Anan Jun 19 '18 at 09:57
  • I guess you need it at least 1px width? So if you set all x coordinates to 1459 the width will be 0, therefore no filling, therefore blur won't work. The 4 points provide you with the straight vertical line, the only difference is width. If you want minimal width you can put 1459,357 1459,643 1460,357 1460,643 but this way the blur is hardly noticeable. – JeB Jun 19 '18 at 10:35
  • `SourceGraphic` not `SourceGraphics`. This has already been told and it won't render in FF (because despite your, and maybe Chrome's, reading of the specs, there is no "*in case the specified value doesn't match a `result` value*" default action there.) – Kaiido Jun 20 '18 at 08:15
  • Thanks for bringing it up – JeB Jun 20 '18 at 08:19
  • Thank you very much, it seems to do the trick adding the x and y and the filterUnits="userSpaceOnUse" made it work – Anan Jun 20 '18 at 10:20