gpt4 book ai didi

xml - 如何在 SVG 中正确引用外部 SVG 文件?

转载 作者:数据小太阳 更新时间:2023-10-29 01:38:47 26 4
gpt4 key购买 nike

你好,我正在制作 SVG/JS map ,它由许多小的 SVG 图形(市区)组成。我将每个图形都放入一个自己的文件中,这样我的主 SVG 文件仍然可以维护并且不会臃肿。

如何正确引用另一个 SVG 中的外部 SVG 文件?

预期结果:在浏览器中打开 1.svg 并看到一个蓝色矩形。它应该如何工作:w3c: use element

所以这是我尝试过的:1.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet href="style.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG- 20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<use xlink:href="another.svg#rectangle"/>
</svg>

另一个.svg:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG- 20010904/DTD/svg10.dtd">
<svg id="rectangle" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="1000" height="1000">
<rect class="blue" x="558.5" y="570" width="5" height="5" />
</svg>

样式.css

.blue { fill: blue; }

结果:

  • Firefox:蓝色矩形(正是我想要的)
  • Chrome:
  • Opera:黑色矩形

注意:我尝试使用图像元素,但它不适用于样式表,即我得到的是黑色矩形而不是蓝色矩形。

重要:当您想要引用另一个 SVG 并且希望引用的 SVG 成为正式文档结构的一部分时,您可以 use AJAX这样做。

https://bugs.webkit.org/show_bug.cgi?id=12499

最佳答案

这回答了最初的问题,但也试图从更广泛的角度回答在 SVG 中引用外部 SVG 文件的问题。

缺乏 SVG 支持

六年后,Chrome 和 Safari 仍然不允许引用/加载外部 SVG 文件

这就是为什么 <use xlink:href="another.svg#rectangle" class="blue"/>适用于 Firefox,但不适用于 WebKit 浏览器。

全部在一个文件中

如果项目负担得起,只需将所有 SVG 文件放在一个父 HTML 或 SVG 文件中。这样,它将在所有三种浏览器中工作:

但是,这并不是真正的外部,这是理所当然的!

为了从缓存中受益并避免重复自己,我们希望将可重复的 SVG 内容保存在外部文件中。

解决方法:通过 JavaScript 插入外部 SVG 文件

将样式和定义保存在一个 SVG 文件中,将 SVG 几何图形保存在其他文件中,然后通过 JavaScript 从后者简单地加载前者。

在纯 SVG 和纯 JavaScript 中

定义我们希望能够使用的内容。 styles-and-defs.svg :

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<style type="text/css" >
<![CDATA[

.blue { fill: blue; }

]]>
</style>

<defs>
<rect id="rectangle" class="blue" width="50" height="50" />
</defs>
</svg>

使用上面创建的几何体,并加载它的定义。 parent.svg :

<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="420" height="120">

<use xlink:href="#rectangle" x="10" y="10" />

<script><![CDATA[

/** When the document is ready, this self-executing function will be run. **/
(function() {

var ajax = new XMLHttpRequest();
ajax.open("GET", "styles-and-defs.svg", true);
ajax.send();

/**
* Append the external SVG to this very SVG.
*
* Notice the use of an SVG selector on the document derived from the AJAX result.
* This is because the full document cannot be included directly into the SVG.
* Trying to include to do so would result in:
* `HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy` in Firefox;
* `Nodes of type '#document' may not be inserted inside nodes of type 'svg'.` in Chrome.
*/
ajax.onload = function(e) {
var parser = new DOMParser();
var ajaxdoc = parser.parseFromString( ajax.responseText, "image/svg+xml" );
document.getElementsByTagName('svg')[0].appendChild( ajaxdoc.getElementsByTagName('svg')[0] );
}

})(); /* END (anonymous function) */

]]></script>
</svg>

这回答了 OP。

在 HTML 中

与纯 SVG 中的基本方法相同:

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>
Load external SVG (HTML)
</title>
<meta name="author" content="Fabien Snauwaert">
</head>

<body>

<svg version="1.1"
baseProfile="full"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:ev="http://www.w3.org/2001/xml-events"
width="420" height="120">
<use xlink:href="#rectangle" x="10" y="10" />
</svg>

<script>

/** When the document is ready, this self-executing function will be run. **/
(function() {

var ajax = new XMLHttpRequest();
ajax.open("GET", "styles-and-defs.svg", true);
ajax.send();

/**
* Append the external SVG to this very SVG.
*
* Notice the use of an SVG selector on the document derived from the AJAX result.
* This is because the full cannot be included directly into the SVG.
* Trying to include to do so would result in:
* `HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy` in Firefox;
* `Nodes of type '#document' may not be inserted inside nodes of type 'svg'.` in Chrome.
*/
ajax.onload = function(e) {
var parser = new DOMParser();
var ajaxdoc = parser.parseFromString( ajax.responseText, "image/svg+xml" );
document.getElementsByTagName('body')[0].appendChild( ajaxdoc.getElementsByTagName('svg')[0] );
}

})(); /* END (anonymous function) */

</script>

</body>
</html>

您当然可以使用 jQuery(或者为什么不用出色的 D3.js )来加载文件。

备注

  • 注意使用<defs> .我相信这是拥有外部 SVG 的好处,您可以使一切保持整洁有序。 (如果没有它,我们将显示两次内容。)
  • 我摆脱了style.css只需将 CSS 放入 styles-and-defs 文件即可。
  • 如果在 HTML 版本中,您观察到父 SVG 和窗口边框之间存在间隙,这是因为“不可见”SVG(具有样式和定义)与任何其他 SVG 一样,是一个 inline。元素。要消除这个差距,只需设置 style="display: block;"在那个 SVG 上。
  • Download all examples here .

SVG 很棒,但支持的似乎太少,但它确实允许做一些很棒的事情。我希望这对那里的一些人有所帮助。

在 OS X 10.12.6 上测试正常:

  • Firefox 59.0.2
  • Chrome 66.0.3359.139
  • Safari 11.0.1

关于xml - 如何在 SVG 中正确引用外部 SVG 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7215009/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com