为什么我的 SVG 数据 URL 在 SVG 数据 URL 内的 HTML 中不显示在 Chrome 中?

Oak*_*Oak 3 html css svg google-chrome html5-canvas

背景

我有一个 SVG 数据 URL 作为SVG 数据 URLbackground-image内部 HTML 元素的属性,<foreignObject>该 URL 充当<img>元素的源。

问题

在 Google Chrome 中,内部 SVG 根本不渲染;而如果整个业务不在图像内,它就会被渲染。我该如何解决这个问题?

等等,什么?为什么?

为什么会在下面,首先我想通过添加树结构和代码示例来完成问题,以澄清上面令人费解的段落。

树:

  • <img src="data:image/svg+xml;utf8,(附录A
    • <svg>(附录B
      • <foreignObject>
        • <html>
          • <div style="background: url('data:image/svg+xml;utf8,
            • <svg>(附录C

附件 C 根本没有渲染,就好像它不存在一样。不过,如果我将展品 A 剪掉,使展品 B 成为顶级元素,那么展品 C 就会渲染得很好。

小代码示例:

<div>Standalone:</div>
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject style="width: 100%; height: 100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='50'><circle cx='50' cy='25' r='25' fill='blue'/></svg>"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>

<div>As image source:</div>
<img style="position:relative" src='data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject style="width: 100%; height: 100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,<svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;100&quot; height=&quot;50&quot;><circle cx=&quot;50&quot; cy=&quot;25&quot; r=&quot;25&quot; fill=&quot;blue&quot;/></svg>"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>'>
Run Code Online (Sandbox Code Playgroud)

最后一点:使用 PNG 数据 URL 代替 SVG 数据 URL 效果很好;当使用 SVG 时,这个问题就会被破坏。

为什么?

将 HTML 放在 an 中<img>可以让 HTML 通过 - 渲染在画布上context.drawImage,然后我会根据canvas.toDataURLHTML 生成图像,这是我的最终目标。这是一种糟糕的标准方法,也被广泛使用的库所采用,例如https://github.com/tsayen/dom-to-image

不过,我的 HTML 带有自己的嵌入式 SVG,这会产生问题中提到的问题。到目前为止,我首先对最里面的 SVG 数据 URL 重复此流程,将它们替换为 PNG 数据 URL,然后才渲染顶级 HTML 元素,从而绕过了这个问题。但现在我想在混合中添加缩放,这使事情变得非常复杂,因为这些 PNG 不会平滑缩放,而且我无法首先缩放,因为这样图像对于它们的元素来说太大了。

(嗯,它适用于可缩放的背景图像,但不适用于不缩放的剪辑路径,而且我也在转换)。

其它浏览器

IE 和 Edge 内部不支持 HTML <foreignObject>,因此这与它们无关。

Firefox 确实支持它,但由于某种原因,它的“独立”版本也不起作用 - 我也想解决这个问题,但它可能属于一个单独的问题。

相关但不重复:

Kai*_*ido 5

您需要对特殊字符进行编码,我不知道到底哪个是罪魁祸首,但是当在整个 <CSSImage url> 上使用encodeURIComponent,然后再次编码整个标记以将其传递到 <img> 中时,一切正常铬合金。

<div>Standalone:</div>
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject style="width: 100%; height: 100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'100'%20height%3D'50'%3E%3Ccircle%20cx%3D'50'%20cy%3D'25'%20r%3D'25'%20fill%3D'blue'%2F%3E%3C%2Fsvg%3E"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>

<div>As image source:</div>
<img style="position:relative" src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2275%22%20height%3D%2250%22%20style%3D%22position%3Arelative%22%3E%3Ccircle%20cx%3D%2225%22%20cy%3D%2225%22%20r%3D%2225%22%20fill%3D%22red%22%20%2F%3E%3CforeignObject%20style%3D%22width%3A%20100%25%3B%20height%3A%20100%25%22%3E%3Chtml%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%3Cstyle%3E.x%20%7Bposition%3A%20absolute%3Bbackground%3A%20url(%22data%3Aimage%2Fsvg%2Bxml%3Butf8%2C%253Csvg%2520xmlns%253D'http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg'%2520width%253D'100'%2520height%253D'50'%253E%253Ccircle%2520cx%253D'50'%2520cy%253D'25'%2520r%253D'25'%2520fill%253D'blue'%252F%253E%253C%252Fsvg%253E%22)%3B%20width%3A%20100%25%3B%20height%3A%20100%25%3B%7D%3C%2Fstyle%3E%3Cdiv%20class%3D%22x%22%3E%3C%2Fdiv%3E%3C%2Fhtml%3E%3C%2FforeignObject%3E%3C%2Fsvg%3E">
Run Code Online (Sandbox Code Playgroud)

另请注意,<foreingObject>和属性在 SVG1.1 中是强制性的,因此省略它们仅在 Chrome 中有效widthheight

所以对于其他仍然需要实现这个新功能的浏览器

<div>Standalone:</div>
<svg xmlns="http://www.w3.org/2000/svg" width="75" height="50" style="position:relative"><circle cx="25" cy="25" r="25" fill="red" /><foreignObject width="100%" height="100%"><html xmlns="http://www.w3.org/1999/xhtml"><style>.x {position: absolute;background: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20width%3D'100'%20height%3D'50'%3E%3Ccircle%20cx%3D'50'%20cy%3D'25'%20r%3D'25'%20fill%3D'blue'%2F%3E%3C%2Fsvg%3E"); width: 100%; height: 100%;}</style><div class="x"></div></html></foreignObject></svg>

<div>As image source:</div>
<img style="position:relative" src="data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2275%22%20height%3D%2250%22%20style%3D%22position%3Arelative%22%3E%3Ccircle%20cx%3D%2225%22%20cy%3D%2225%22%20r%3D%2225%22%20fill%3D%22red%22%20%2F%3E%3CforeignObject%20width%3D%22100%%22%20height%3D%22100%%22%3E%3Chtml%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%3Cstyle%3E.x%20%7Bposition%3A%20absolute%3Bbackground%3A%20url(%22data%3Aimage%2Fsvg%2Bxml%3Butf8%2C%253Csvg%2520xmlns%253D'http%253A%252F%252Fwww.w3.org%252F2000%252Fsvg'%2520width%253D'100'%2520height%253D'50'%253E%253Ccircle%2520cx%253D'50'%2520cy%253D'25'%2520r%253D'25'%2520fill%253D'blue'%252F%253E%253C%252Fsvg%253E%22)%3B%20width%3A%20100%25%3B%20height%3A%20100%25%3B%7D%3C%2Fstyle%3E%3Cdiv%20class%3D%22x%22%3E%3C%2Fdiv%3E%3C%2Fhtml%3E%3C%2FforeignObject%3E%3C%2Fsvg%3E">
Run Code Online (Sandbox Code Playgroud)