SVG filters fuzzy in Safari under some circumstances

一世执手 提交于 2019-12-22 12:33:13

问题


I have an page with an interactive SVG which looks fine on all browsers (Firefox, Chrome, even IE/Edge) except Safari where everything affected by one of the SVG filters turns into a fuzzy mush (looks like something rendered onto a low-resolution canvas which got scaled up using bilinear interpolation).

Here now a small test case where the problem also appears:

<svg>
  <defs>
    <filter id="filter" y="-100" x="-100" height="300" width="300">
      <feGaussianBlur in="SourceAlpha" stdDeviation="3.5"></feGaussianBlur>
      <feColorMatrix type="matrix" values="0 0 0 2 0   0 0 0 2 0   0 0 0 0 0   0 0 0 1 0" result="lightenedBlur"></feColorMatrix>
      <feMerge>
        <feMergeNode in="lightenedBlur"></feMergeNode>
        <feMergeNode in="SourceGraphic"></feMergeNode>
      </feMerge>
    </filter>
  </defs>
  <g>
    <rect x="10" y="10" width="100" height="100" fill="blue" filter="url(#filter)"></rect>
  </g>
</svg>

How it looks on Apple Safari 11 (on OS X 10.13):

Compare that to Google Chrome and Mozilla Firefox respectively:

When looking at other SVG filter demo pages on the web though the effect apparently isn't there. Not quite sure what exactly causes it. What I noticed is that the issue becomes more apparent the larger the filter area is (controlled through the width/height attributes of <filter>).

Is this a known issue? Under what circumstances does it occur? What are reasonable workarounds?


回答1:


This is not a bug. Safari is punishing you for incorrect syntax in your filter declaration:

<filter id="filter" y="-100" x="-100" height="300" width="300">

According to spec, this should be read as height="30000%" and width="30000%". Safari is saying "ok I guess you meant this" and adjusting the filter resolution automatically so it doesn't allocate a huge piece of memory to this very large buffer -> hence crappy resolution.

If you meant 300% - then you need to put 300%. This is one fix:

<filter id="filter" y="-100%" x="-100%" height="300%" width="300%">

If you meant 300px (really userSpace units) - then this is another fix:

<filter id="filter" y="100" x="-100" height="300" width="300" filterUnits="userSpaceOnUse">

You must explicitly tell Safari that you mean pixels by specifying userSpaceOnUse (otherwise it uses the silent default objectBoundingBox)

Another fix - is to over-ride Safari's filter resolution adjustment by explicitly specifying a filterRes. filterRes has been deprecated in the new Filters 1.0 spec and already removed from latest Chrome & Firefox, but Safari still supports it. Since this will result in a big memory hit(and it's hard to believe that you meant to size your filter as you did) - this is not recommended. But whatever - for completeness.

<filter id="filter" y="-100" x="-100" height="300" width="300" filterRes="100000">

(Two other minor notes - you can make your filters less wordy by using self-closing elements. And the blur adjustment you're doing doesn't lighten the blur, it just dials up the opacity fwiw.)



来源:https://stackoverflow.com/questions/47942581/svg-filters-fuzzy-in-safari-under-some-circumstances

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!