Javascript 如何在svg元素中使用z索引?

Javascript 如何在svg元素中使用z索引?,javascript,jquery,svg,z-index,Javascript,Jquery,Svg,Z Index,我在我的项目中使用svg圆圈,如下所示 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 120"> <g> <g id="one"> <circle fill="green" cx="100" cy="105" r="20" /> </g> <g id="two">

我在我的项目中使用svg圆圈,如下所示

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 120">
    <g>
        <g id="one">
            <circle fill="green" cx="100" cy="105" r="20" />
        </g>
        <g id="two">
            <circle fill="orange" cx="100" cy="95" r="20" />
        </g>
    </g>
</svg>

我使用
g
标记中的z索引来显示第一个元素。在我的项目中,我只需要使用z-index值,但不能将z-index用于svg元素。我在谷歌上搜索了很多,但没有找到任何相关的信息。 因此,请帮助我在svg中使用z索引

下面是尝试反转
#一个
#两个
的方法。看看这把小提琴:

更新

在SVG中,z索引由元素在文档中的显示顺序定义。如果需要,您也可以查看此页面:

规范 在SVG规范版本1.1中,呈现顺序基于文档顺序:

first element -> "painted" first
参考

SVG文档片段中的元素有一个隐式的绘图顺序,SVG文档片段中的第一个元素首先得到“绘制的”。后续图元绘制在先前绘制的图元之上


解决方案(清洁更快) 您应该将绿色圆圈作为要绘制的最新对象。因此,交换这两个元素


您可以使用


绿色圆圈显示在顶部。

另一种解决方案是使用div,它确实使用zIndex来包含SVG元素。如下所示:

正如其他人所说,z-index是由元素在DOM中的显示顺序定义的。如果手动重新排序html不是一个选项或者很困难,那么可以使用D3重新排序SVG组/对象

使用D3更新DOM顺序并模拟Z索引功能

在最基本的层次上(如果您不使用ID进行任何其他操作),您可以使用元素ID作为z索引的替代,并使用这些ID重新排序。除此之外,你几乎可以让你的想象力失控

代码片段中的示例

var circles=d3。选择全部('circle')
var label=d3。选择('svg')。追加('text'))
.attr('transform','translate(+[5100]+'))
var zOrders={
id:circles[0].map(函数(cv){return cv.id;}),
xPos:圆[0].映射(函数(cv){return cv.cx.baseVal.value;}),
yPos:圆[0].映射(函数(cv){return cv.cy.baseVal.value;}),
半径:圆[0]。映射(函数(cv){return cv.r.baseVal.value;}),
客户订单:[3,4,1,2,5]
}
var setOrderBy='IDs';
var setOrder=d3.0;
label.text(setOrderBy);
circles.data(zOrders[setOrderBy])
圆。排序(setOrder)

使用D3:

如果要按与数据相反的顺序添加元素,请使用:

.insert('g', ":first-child")
而不是。追加


SVG没有z指数。但是svg根据元素在DOM中的位置确定哪些元素是最上面的。因此,您可以删除该对象并将其放置在svg的末尾,使其成为“最后渲染的”元素。然后,该图像被渲染为“最上面的”


使用jQuery:

function moveUp(thisObject){
    thisObject.appendTo(thisObject.parents('svg>g'));
}
d3.selection.prototype.moveUp = function() {
    return this.each(function() {
        this.parentNode.appendChild(this);
    });
};
用法:

moveUp($('#myTopElement'));
myTopElement.moveUp();

使用D3.js:

function moveUp(thisObject){
    thisObject.appendTo(thisObject.parents('svg>g'));
}
d3.selection.prototype.moveUp = function() {
    return this.each(function() {
        this.parentNode.appendChild(this);
    });
};
用法:

moveUp($('#myTopElement'));
myTopElement.moveUp();

使用D3:

如果要按顺序重新插入每个选定元素,将其作为其父元素的最后一个子元素

selection.raise()

如前所述,SVG按顺序渲染,不考虑z索引(目前)。可能只是将特定元素发送到其父元素的底部,以便最后渲染

function bringToTop(targetElement){
  // put the element at the bottom of its parent
  let parent = targetElement.parentNode;
  parent.appendChild(targetElement);
}

// then just pass through the element you wish to bring to the top
bringToTop(document.getElementById("one"));
为我工作

更新 如果您有一个包含组的嵌套SVG,则需要将该项从其父节点中取出

function bringToTopofSVG(targetElement){
  let parent = targetElement.ownerSVGElement;
  parent.appendChild(targetElement);
}

SVG的一个很好的特性是,每个元素都包含它的位置,而不管它嵌套在哪个组中:+1:

截至回答之日发布的干净、快速和简单的解决方案并不令人满意。它们是在SVG文档缺少z顺序这一有缺陷的语句之上构建的。图书馆也不是必需的。一行代码可以执行大多数操作来操纵对象或对象组的z顺序,这在开发在x-y-z空间中移动2D对象的应用程序时可能是必需的

Z顺序肯定存在于SVG文档片段中

所谓SVG文档片段是从基本节点类型SVGElement派生的元素树。SVG文档片段的根节点是SVGSVGElement,它对应于HTML5标记。svggement对应于标记,并允许聚合子元素

在SVGElement上使用z-index属性(如CSS中的那样)将破坏SVG呈现模型。W3C SVG建议v1.1第二版第3.3节和第3.4节指出,SVG文档片段(SVGSVGElement的后代树)是使用树的深度优先搜索来呈现的。该方案在任何意义上都是z阶

Z顺序实际上是一种计算机视觉快捷方式,可以避免真实3D渲染的需要以及光线跟踪的复杂性和计算需求。SVG文档片段中元素的隐式z索引的线性方程

z-index = z-index_of_svg_tag + depth_first_tree_index / tree_node_qty
这一点很重要,因为如果要将正方形下方的圆移动到正方形上方,只需在圆之前插入正方形即可。这可以用JavaScript轻松完成

支持方法

SVGElement实例有两种方法支持简单和简单的z顺序操作

  • parent.removeChild(子级)
  • parent.insertBefore(child,childRef)
不会造成混乱的正确答案

由于SVGGElement(标记)可以像SVGCIRCLEEElement或任何其他形状一样轻松地删除和插入,因此Adobe产品和其他gra的典型图像层
var Target = document.getElementById(event.currentTarget.id);
var svg = document.getElementById("SVGEditor");
svg.insertBefore(Target, svg.lastChild.nextSibling);