Javascript SVG 重新排序 z-index(Raphael 可选)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6566406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 22:19:10  来源:igfitidea点击:

SVG re-ordering z-index (Raphael optional)

javascriptsvgraphael

提问by Miles

How can I reorder Raphael or their underlying SVG elements after creation. Better yet, do something like layers exist in SVG?

创建后如何重新排序 Raphael 或其底层 SVG 元素。更好的是,SVG 中是否存在图层之类的东西?

Ideally I would like two or more layers in which to place elements at any time; A background and a foreground layer. If that is not an option, popping elements to the front would be ok, and pushing it to the back would be better in this particular case.

理想情况下,我希望随时可以在其中放置两个或更多层;一个背景层和一个前景层。如果这不是一个选项,那么将元素弹出到前面就可以了,在这种特殊情况下将它推到后面会更好。

Thanks,

谢谢,

回答by Phrogz

Gimme the Code!

给我代码!

// move element "on top of" all others within the same grouping
el.parentNode.appendChild(el); 

// move element "underneath" all others within the same grouping
el.parentNode.insertBefore(el,el.parentNode.firstChild);

// move element "on top of" all others in the entire document
el.ownerSVGElement.appendChild(el); 

// move element "underneath" all others in the entire document
el.ownerSVGElement.appendChild(el,el.ownerSVGElement.firstChild); 

Within Raphael specifically, it's even easier by using toBack()and toFront():

特别是在 Raphael 中,使用toBack()and更容易toFront()

raphElement.toBack()  // Move this element below/behind all others
raphElement.toFront() // Move this element above/in front of all others

Details

细节

SVG uses a "painters model"when drawing objects: items that appear later in the document are drawn after (on top of) elements that appear earlier in the document. To change the layering of items, you must re-order the elements in the DOM, using appendChildor insertBeforeor the like.

SVG在绘制对象时使用“画家模型”:在文档中较晚出现的项目在文档中较早出现的元素之后(在其顶部)绘制。要改变项目的层次感,你必须重新在DOM元素,使用appendChildinsertBefore等。

You can see an example of this here: http://phrogz.net/SVG/drag_under_transformation.xhtml

你可以在这里看到一个例子:http: //phrogz.net/SVG/drag_under_transformation.xhtml

  1. Drag the red and blue objects so that they overlap.
  2. Click on each object and watch it pop to the top. (The yellow circles are intended to always be visible, however.)
  1. 拖动红色和蓝色对象,使它们重叠。
  2. 单击每个对象并观看它弹出顶部。(然而,黄色圆圈旨在始终可见。)

The re-ordering of elements on this example is done by lines 93/94 of the source code:

此示例中元素的重新排序由源代码的第 93/94 行完成:

el.addEventListener('mousedown',function(e){
  el.parentNode.appendChild(el); // move to top
  ...
},false);

When the mouse is pushed down on an element, it is moved to be the last element of all its siblings, causing it to draw last, "on top" of all others.

当鼠标在一个元素上被按下时,它被移动到它所有兄弟元素的最后一个元素,导致它在所有其他元素的“顶部”最后绘制。

回答by Herman Schaaf

If you're using Raphael, popping elements backwards and forwards is very straightforward:

如果您使用 Raphael,向后和向前弹出元素非常简单:

element.toBack()
element.toFront()

Here's the relevant documentation.

这是相关文档

回答by Spadar Shut

There's no z-index in SVG, objects that are later in the code appear above the first ones. So for your needs, you can move the node to the start of the tree or the end of it.

SVG 中没有 z-index,代码后面的对象出现在第一个上面。因此,根据您的需要,您可以将节点移动到树的开头或结尾。

<g>(group) element is a generic container in svg, so they can be layers for you. Just move nodes between the groups to achieve what you need.

<g>(group) 元素是 svg 中的通用容器,因此它们可以是您的图层。只需在组之间移动节点即可实现您的需要。

回答by Spadar Shut

If you predefine your graphic objects, you can then layer them in different orders as time evolves:

如果您预定义图形对象,则可以随着时间的推移以不同的顺序将它们分层:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1000 1000" width="400" height="400">
  <rect x="0" y="0" width="1000" height="1000" fill="black"/>
  <defs>
    <rect id="a1" x="0"   y="0"   width="500" height="500" fill="red"/>
    <rect id="a2" x="100" y="100" width="500" height="500" fill="blue"/>
  </defs>
  <g> 
    <use xlink:href="#a1"/>
    <use xlink:href="#a2"/>
    <set attributeName="visibility"  to="hidden" begin="2s"/> 
  </g>
  <g visibility="hidden"> 
    <use xlink:href="#a2"/>
    <use xlink:href="#a1"/>
    <set attributeName="visibility"  to="visible" begin="2s"/> 
  </g>
</svg>

回答by sgimeno

I haven't tried it yet but SVG render orderlooks like it could be a solution. And also 'z-index' is coming, it is already in proposal

我还没有尝试过,但SVG 渲染顺序看起来可能是一个解决方案。而且“z-index”即将推出,它已经在提案中

回答by FloydATC

Actually, I think appendChild() alone will copythe element and not just moveit. This may not be a problem but if you want to avoid duplicates I suggest something like this:

实际上,我认为 appendChild() 单独会复制元素,而不仅仅是移动它。这可能不是问题,但如果您想避免重复,我建议如下:

el.parentNode.appendChild(el.parentNode.removeChild(el));