使用纯 JS 从另一个 SVG 元素插入 SVG 元素
Inserting SVG elements from another SVG element with plain JS
我正在尝试使用 svg.js 库 (https://svgjs.dev) 动态呈现 SVG 元素的内容。在创建基本元素(如线条、多边形和简单文本)并使用它们的属性时一切正常。
现在,我想使用现成的 SVG(在页面上的隐藏 div 中或通过其他方式提供)用更复杂的元素扩展绘图,我需要以某种方式 'clone' 到主 SVG 元素,并调整大小和位置。
下图是我想要完成的示例:矩形是用 svgjs 创建的 svg.polygon().plot(... )
,我想添加树。
执行此操作的 simple/proper 方法是什么?
再一次,睡个好觉提供了正确的答案,而且比我预期的要容易得多。
事实证明,只需要一个 use
,带有 svg 元素 ID 和一个可选的 URL 来加载 SVG 文件,这样可以避免将 SVG 嵌入到页面中:
// the definition of the object to embed
// holds the item id, and transformation data
var item = ...;
var g = svg
.group()
.use(
item.src,
resURL + '/svg/sprites.svg')
.transform({
translateX : item.x,
translateY : item.y });
对于域外的 SVG,您可能需要以不同方式加载它们。
根据要求,下面是一个部分但更详细的代码示例;添加完整代码会使解决方案难以理解。
免责声明:我还没有进行优化/重构,所以是的,数据和代码可能还有很大的改进空间。
数据是一个 JSON 结构,如下所示:
{
"items" : {
"item1" : {
"points" : [[1600,200],[2300,200],[2300,600],[1600,600],[1600,200]],
"fill" : "rgba(144, 238, 144, 0.3)",
"stroke" : "#228B22"
},
"item2" : {
"src":"sprite1"
"style":{
"opacity" : 0.3
},
"position":{
"x" : -360,
"y" : 75,
"scale" : 0.8
},
}
},
}
处理过程是这样的:
var svg = SVG("#drawing-" + floor.key)
Object.keys(floor.items).forEach(function(key,index) {
var item = floor.items[key];
if (item.hasOwnProperty('points')) {
var polygon = svg
.polygon()
.stroke({
color: item.stroke })
.fill(item.fill);
polygon.plot(item.points);
}
else if (item.hasOwnProperty('src')) {
var g = svg
.group()
.use(item.src, resURL + '/svg/plan-sprites.svg')
.transform({
translateX : item.position.x,
translateY : item.position.y,
scale : item.position.scale || 1.})
.css(item.style || { });
}
});
完成后,页面如下所示(简化):
<svg id="drawing-curte" class="hwb-drawing"
<g id="viewport">
<polygon points="1600,200 2300,200 2300,600 1600,600 1600,200" stroke="#228b22" fill="#90ee90"></polygon>
<g><use xlink:href="/resources/svg/plan-sprites.svg#sprite1" transform="matrix(1,0,0,1,1550,150)"></use></g>
</g>
</svg>
我正在尝试使用 svg.js 库 (https://svgjs.dev) 动态呈现 SVG 元素的内容。在创建基本元素(如线条、多边形和简单文本)并使用它们的属性时一切正常。
现在,我想使用现成的 SVG(在页面上的隐藏 div 中或通过其他方式提供)用更复杂的元素扩展绘图,我需要以某种方式 'clone' 到主 SVG 元素,并调整大小和位置。
下图是我想要完成的示例:矩形是用 svgjs 创建的 svg.polygon().plot(... )
,我想添加树。
执行此操作的 simple/proper 方法是什么?
再一次,睡个好觉提供了正确的答案,而且比我预期的要容易得多。
事实证明,只需要一个 use
,带有 svg 元素 ID 和一个可选的 URL 来加载 SVG 文件,这样可以避免将 SVG 嵌入到页面中:
// the definition of the object to embed
// holds the item id, and transformation data
var item = ...;
var g = svg
.group()
.use(
item.src,
resURL + '/svg/sprites.svg')
.transform({
translateX : item.x,
translateY : item.y });
对于域外的 SVG,您可能需要以不同方式加载它们。
根据要求,下面是一个部分但更详细的代码示例;添加完整代码会使解决方案难以理解。
免责声明:我还没有进行优化/重构,所以是的,数据和代码可能还有很大的改进空间。
数据是一个 JSON 结构,如下所示:
{
"items" : {
"item1" : {
"points" : [[1600,200],[2300,200],[2300,600],[1600,600],[1600,200]],
"fill" : "rgba(144, 238, 144, 0.3)",
"stroke" : "#228B22"
},
"item2" : {
"src":"sprite1"
"style":{
"opacity" : 0.3
},
"position":{
"x" : -360,
"y" : 75,
"scale" : 0.8
},
}
},
}
处理过程是这样的:
var svg = SVG("#drawing-" + floor.key)
Object.keys(floor.items).forEach(function(key,index) {
var item = floor.items[key];
if (item.hasOwnProperty('points')) {
var polygon = svg
.polygon()
.stroke({
color: item.stroke })
.fill(item.fill);
polygon.plot(item.points);
}
else if (item.hasOwnProperty('src')) {
var g = svg
.group()
.use(item.src, resURL + '/svg/plan-sprites.svg')
.transform({
translateX : item.position.x,
translateY : item.position.y,
scale : item.position.scale || 1.})
.css(item.style || { });
}
});
完成后,页面如下所示(简化):
<svg id="drawing-curte" class="hwb-drawing"
<g id="viewport">
<polygon points="1600,200 2300,200 2300,600 1600,600 1600,200" stroke="#228b22" fill="#90ee90"></polygon>
<g><use xlink:href="/resources/svg/plan-sprites.svg#sprite1" transform="matrix(1,0,0,1,1550,150)"></use></g>
</g>
</svg>