问题
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