使用纯 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>