SVG重新排序z-index(拉斐尔可选)

时间:2011-07-04 00:34:36

标签: javascript svg raphael

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

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

谢谢,

6 个答案:

答案 0 :(得分:92)

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

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

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

详细

SVG在绘制对象时使用"painters model":文档中稍后出现的项目是在文档中较早出现的元素之后(在其上方)绘制的。要更改项目的分层,您必须使用appendChildinsertBefore等对DOM中的元素进行重新排序。

您可以在此处查看此示例:http://phrogz.net/SVG/drag_under_transformation.xhtml

  1. 拖动红色和蓝色对象,使它们重叠。
  2. 点击每个对象并观看它弹出到顶部。 (但是,黄色圆圈始终是可见的。)
  3. 此示例中元素的重新排序由源代码的第93/94行完成:

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

    当鼠标按下一个元素时,它会被移动到它所有兄弟姐妹的最后一个元素,导致它最后画出,“在所有其他兄弟上面”。

答案 1 :(得分:40)

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

element.toBack()
element.toFront()

这是relevant documentation

答案 2 :(得分:4)

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

我还没有尝试过,但SVG render order看起来可能是一个解决方案。而且'z-index'即将到来,它已经在proposal

答案 5 :(得分:-2)

实际上,我认为appendChild()将复制元素而不仅仅是移动它。这可能不是问题,但如果你想避免重复,我建议这样的事情:

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