SVG滤镜中feTile生成的圆点在iOS失效,Chrome正常
iOS Safari下SVG滤镜feImage+feTile不显示圆点的解决方案
看起来你遇到的是iOS Safari对SVG滤镜中feImage引用内部元素的兼容性问题——Chrome等现代浏览器支持feImage直接引用同一SVG文档内的元素,但iOS Safari在处理这种情况时经常有bug,导致feTile无法正确渲染出圆点效果。
问题根源
iOS Safari的SVG滤镜实现对feImage引用内部元素(比如你的#circle)的支持不完善,即使你设置了width/height,它也可能无法正确解析这个内部资源,进而导致后续的feTile没有可平铺的内容。
修复方案
我们可以用两种方式解决这个问题:
方案1:替换feImage+feTile为fePattern
用<fePattern>来定义圆点图案,这是更兼容的方式,iOS Safari对fePattern的支持更稳定:
<svg height="80" width="500" xmlns="http://www.w3.org/2000/svg"> <defs> <!-- 用fePattern定义圆点图案 --> <pattern id="dotPattern" width="6" height="6" patternUnits="userSpaceOnUse"> <circle cx="3" cy="3" r="2" fill="#FFFFFF"></circle> </pattern> <filter height="100%" id="filter"> <feMorphology in="SourceAlpha" operator="dilate" radius="2.5" result="MORPH1"></feMorphology> <feColorMatrix in="MORPH1" result="GREYED" type="matrix" values="0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.5 0"></feColorMatrix> <feMorphology in="SourceAlpha" operator="dilate" radius="1.5" result="MORPH2"></feMorphology> <feColorMatrix in="MORPH2" result="WHITENED" type="matrix" values="-1 0 0 1 0, 0 -1 0 1 0, 0 0 -1 1 0, 0 0 0 0.8 0"></feColorMatrix> <!-- 用feFlood+feComposite来应用pattern --> <feFlood flood-color="url(#dotPattern)" result="3dot"></feFlood> <feComposite in="3dot" in2="SourceGraphic" operator="in" result="comp"></feComposite> <feMerge> <feMergeNode in="GREYED"></feMergeNode> <feMergeNode in="WHITENED"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> <feMergeNode in="comp"></feMergeNode> </feMerge> </filter> </defs> <text text-anchor="start" alignment-baseline="hanging" font-size="48" x="20" y="20" fill="#803cac" stroke="#000000" stroke-width="1" filter="url(#filter)">TEXT HERE</text> </svg>
方案2:将circle转换为data URI传入feImage
如果坚持用feImage,可以把circle转换成base64编码的SVG data URI,这样iOS Safari能正确识别这个外部资源:
<svg height="80" width="500" xmlns="http://www.w3.org/2000/svg"> <defs> <filter height="100%" id="filter"> <feMorphology in="SourceAlpha" operator="dilate" radius="2.5" result="MORPH1"></feMorphology> <feColorMatrix in="MORPH1" result="GREYED" type="matrix" values="0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.8 0 0 0 0 0 0.5 0"></feColorMatrix> <feMorphology in="SourceAlpha" operator="dilate" radius="1.5" result="MORPH2"></feMorphology> <feColorMatrix in="MORPH2" result="WHITENED" type="matrix" values="-1 0 0 1 0, 0 -1 0 1 0, 0 0 -1 1 0, 0 0 0 0.8 0"></feColorMatrix> <!-- 使用data URI代替内部元素引用 --> <feImage href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iNiIgd2lkdGg9IjYiPjxjaXJjbGUgY3g9IjMiIGN5PSIzIiByPSIyIiBmaWxsPSIjRkZGRkZGIi8+PC9zdmc+" width="6" height="6" result="circleImg"></feImage> <feTile result="3dot"></feTile> <feComposite in="3dot" in2="SourceGraphic" operator="in" result="comp"></feComposite> <feMerge> <feMergeNode in="GREYED"></feMergeNode> <feMergeNode in="WHITENED"></feMergeNode> <feMergeNode in="SourceGraphic"></feMergeNode> <feMergeNode in="comp"></feMergeNode> </feMerge> </filter> </defs> <text text-anchor="start" alignment-baseline="hanging" font-size="48" x="20" y="20" fill="#803cac" stroke="#000000" stroke-width="1" filter="url(#filter)">TEXT HERE</text> </svg>
改动说明
- 方案1中,我们用
<fePattern>定义了6x6的圆点图案(和你原来的circle位置尺寸匹配),然后用feFlood填充这个图案,替代原来的feImage+feTile组合,这是SVG标准中定义重复图案的更规范方式,兼容性更好。 - 方案2中,把原来的circle元素转换成了base64编码的data URI,这样
feImage会把它当作外部资源加载,iOS Safari能正确解析并让feTile平铺。同时我们把feImage的width/height改成了6(和图案尺寸一致),确保平铺的比例正确。
这两种方案都能解决iOS Safari上圆点不显示的问题,同时保留你原来的其他滤镜效果。
内容的提问来源于stack exchange,提问作者dottodot
相关产品推荐
相关产品推荐

