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

IT技术 javascript svg raphael
2021-01-14 19:28:24

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

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

谢谢,

6个回答

给我代码!

// 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); 

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

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

细节

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

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

  1. 拖动红色和蓝色对象,使它们重叠。
  2. 单击每个对象并观看它弹出顶部。(然而,黄色圆圈旨在始终可见。)

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

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

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

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

element.toBack()
element.toFront()

这是相关文档

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

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

但是,如果我希望分层成为一个独立于分组的概念怎么办?例如,我有两个身体部位形状,一个用于语料库,另一个用于手臂。两个部分都由两个独立的形状组成:一个用于描边轮廓,另一个用于填充。并且它们需要以这种方式分层:{手臂填充} {身体填充} {手臂描边} {身体描边} 使其啮合在一起而不重叠它们的轮廓(轮廓需要平滑地勾勒出它们的轮廓)。但是我需要将手臂填充与手臂描边和身体填充与身体描边分组以便更容易地转换它们:/如何将分组与查看分开?
2021-03-22 19:28:24

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

<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>

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