SVG叠加会导致失真。

11

我正在尝试使用SVG堆叠技术,使多个图标堆叠在一个文件中,仅需要浏览器进行单个HTTP请求。该技术在此处有详细介绍。

基本思想是将多个SVG元素放入单个SVG文件中,并使用CSS样式隐藏除当前要显示的图标之外的所有图标。您可以使用CSS :target选择器选择当前要显示的图标。

这种技术对我很有效,但是将多个图标堆叠会导致显示的图标出现奇怪的扭曲,即使所有其他图标都被隐藏了。

在我的示例中,我简化为仅堆叠两个图标:美国国旗图标和英国国旗图标。

(简化后的)SVG文件如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<svg id="svg153" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="480" width="640" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/">

    <svg:style 
        xmlns:svg="http://www.w3.org/2000/svg" type="text/css">
        .i { display: none; }
        .i:target { display: block; }
    </svg:style>

    <svg:svg id="uk" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
       <!-- SVG elements to draw UK flag -->
    </svg:svg>

    <svg:svg id="us" xmlns:svg="http://www.w3.org/2000/svg" class = "i" height="480" width="640" version="1.1">
       <!-- SVG elements to draw US flag --> 
    </svg:svg>
</svg>

请注意,CSS样式是嵌入在SVG文件中的,在<svg::style>元素中。 CSS样式很简单:

.i { display: none; }
.i:target { display: block; }

通过这种方式,任何具有class="i"svg::svg元素都会自动隐藏,除非我们在SVG URL中特别指定它。因此,要显示美国国旗图标,我将使用以下HTML片段:

这样,除非我们专门针对该SVG URL进行目标设置,否则带有class="i"svg::svg元素都会自动隐藏。因此,如果要显示美国国旗图标,可以使用上述HTML代码。

<img 
    src="flags.svg#us" 
    width="80" 
    height="60" 
    alt="SVG Stacked Image" 
/>
当然,要显示英国国旗,我需要将其更改为 src =“flags.svg#uk”
总之,所有这些都非常有效...除了在堆叠图像时在Firefox和Chrome中发生的奇怪图像失真。
这是我从SVG文件中删除(隐藏)英国国旗时美国国旗的屏幕截图:
如您所见,它看起来很好。
但是当我将它放在英国国旗前面时,它看起来像:
正如您所见,图像变得奇怪扭曲 - 它几乎看起来像在压缩图像中获得很多“伪像”时低质量JPEG的情况。
那么这到底是怎么回事?与美国国旗图标一起堆叠的其他图像都是不可见的,为什么它们会影响可见图标?
我在谷歌上搜索了很多答案,尽管SVG堆叠技术确实存在许多问题和“陷阱”,但它们都涉及跨浏览器兼容性。 但是,在包括IE9在内的大多数较新的浏览器上,该技术运行良好。 而且,失真现象在Firefox和Chrome中都有发生,因此这不太可能是一些跨浏览器问题,而更可能是我做错了什么。
那么,当我应用SVG堆叠技术时,到底是什么导致了这种奇怪的失真?

1
你能提供一个Fiddle吗? - user2570380
使用不透明度和显示属性,能够获得相同的效果吗? - Michael Mullany
有完整的代码可以玩弄一下肯定是很好的(也许你可以试试用非常基本的条纹图标来达到相同的效果)。不过,从您的屏幕截图来看,似乎与反锯齿有关:浏览器将反锯齿像素的颜色合并在一起,在去除背景时无法正确地重新绘制它们。对于您的目的,有几个建议:将白色条纹绘制为不透明的白色(或者在旗帜上绘制一个白色背景),或者设置 shape-rendering:cripsEdges。但这是有缺陷的行为,我很惊讶它在Chrome和Firefox中都会出现问题。 - AmeliaBR
为什么不将它们分成两个不同的SVG文件。将它们放在一个div中。并使用绝对定位将它们对齐在一起?这要么是浏览器的问题,要么是文件显示出来因为有一个黑色背景。 - Nikk
2
Boris,这里的重点是要减少浏览器请求并仅使用一个SVG文件。分离将违背此目的。 - Kelderic
2个回答

1

我不清楚堆栈和目标的概念,但是我知道两种简单的方法...也许这些方法可以更容易地帮助你。

当您从网络或计算机中选择不同的svg图标,但每个图标都是单独的时候,您可以使用网站'icomoon.io'。在该网站上,我们可以从在线库或计算机中选择不同的图标。打开'https://icomoon.io/app/',选择“导入图标”以上传计算机中的自定义图标。在页面底部,有“从库添加图标...”以从在线库中选择图标。从“选择”工具(顶部)中选择所需的多个图标。选择多个图标后,在底部选择“生成SVG、PNG、PDF”按钮。然后,要将它们合并到一个文件中,请单击位于左下角第一个按钮的“下载”选项旁边的“设置图标”,选择“包括平铺(CSS Sprite)”。根据需要放置适当的边距和每行的图标数,然后下载带有其xml代码的组合精灵demo.html文件和样式定义style.css。
当您已经使用“AI”或任何其他软件创建了多个图标的单个SVG文件时,只需将该文件上传(导入)到icomoon.io,并单击“生成SVG、PNG、PDF”按钮并下载精灵xml文件即可。

还有一件事.. 当SVG图标中有多种颜色时,有时会出现问题。单色SVG在任何地方都可以正常工作,但是彩色SVG有几种方法可以完美生成它们,否则它们就不会给人以清晰的外观。 - Aabha Pandey

0

我尝试使用自己的简单SVG,它运行良好,没有发生奇怪的扭曲。因此,我猜测是你们用于英国和美国的SVG出了问题。

http://pastebin.com/dxVtTQKF


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接