我正在我的项目中使用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-index来显示第一个元素。在我的项目中,我只需要使用z-index值,但我不能将z-index用于我的svg元素。我google了很多,但我找不到任何相对的东西。
所以请帮我在我的svg中使用z-index。
以下是DEMO.
答案 0 :(得分:136)
在SVG规范1.1版中,渲染顺序基于文档顺序:
first element -> "painted" first
SVG文档片段中的元素具有隐式绘制顺序,SVG文档片段中的第一个元素得到&#34;绘制&#34;第一即可。后续元素绘制在先前绘制的元素之上。
您应该将绿色圆圈作为要绘制的最新对象。所以交换这两个元素。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="30 70 160 120">
<!-- First draw the orange circle -->
<circle fill="orange" cx="100" cy="95" r="20"/>
<!-- Then draw the green circle over the current canvas -->
<circle fill="green" cx="100" cy="105" r="20"/>
</svg>
&#13;
这是您jsFiddle的分支。
标记use
,其属性为xlink:href
,值为元素的ID。请记住,即使结果看起来不错,也可能不是最佳解决方案。有一点时间,这里是规范SVG 1.1 "use" Element的链接。
目的:
避免要求作者修改引用的文档以向根元素添加ID。
<svg xmlns="http://www.w3.org/2000/svg" viewBox="30 70 160 120">
<!-- First draw the green circle -->
<circle id="one" fill="green" cx="100" cy="105" r="20" />
<!-- Then draw the orange circle over the current canvas -->
<circle id="two" fill="orange" cx="100" cy="95" r="20" />
<!-- Finally draw again the green circle over the current canvas -->
<use xlink:href="#one"/>
</svg>
&#13;
SVG 2 Specification是下一个主要版本,仍然支持上述功能。
SVG中的元素以三维方式定位。除了它们在SVG视口的x和y轴上的位置之外,SVG元素也位于z轴上。 z轴上的位置定义了它们的绘制顺序。
沿z轴,元素被分组到堆叠上下文中。
3.4.1. Establishing a stacking context in SVG
...
堆叠上下文是概念性工具,用于描述在呈现文档时元素必须一个在另一个上面的顺序,...
答案 1 :(得分:28)
尝试反转#one
和#two
。看看这个小提琴:http://jsfiddle.net/hu2pk/3/
<强> Update
强>
在SVG中, z-index由元素在文档中出现的顺序定义。如果需要,您也可以查看此页面:https://stackoverflow.com/a/482147/1932751
答案 2 :(得分:21)
正如其他人所说,z-index是由元素在DOM中出现的顺序定义的。如果手动重新排序您的html不是一个选项或者很难,您可以使用D3来重新排序SVG组/对象。
在最基本的级别(如果您没有使用其他ID),您可以使用元素ID作为z-index的替代,并重新排序。除此之外,你几乎可以让你的想象力疯狂。
代码段中的示例
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 100">
<circle id="1" fill="green" cx="50" cy="40" r="20"/>
<circle id="2" fill="orange" cx="60" cy="50" r="18"/>
<circle id="3" fill="red" cx="40" cy="55" r="10"/>
<circle id="4" fill="blue" cx="70" cy="20" r="30"/>
<circle id="5" fill="pink" cx="35" cy="20" r="15"/>
</svg>
var circles = d3.selectAll('circle')
基本理念是:
使用D3选择SVG DOM元素。
var zOrders = {
IDs: circles[0].map(function(cv){ return cv.id; }),
xPos: circles[0].map(function(cv){ return cv.cx.baseVal.value; }),
yPos: circles[0].map(function(cv){ return cv.cy.baseVal.value; }),
radii: circles[0].map(function(cv){ return cv.r.baseVal.value; }),
customOrder: [3, 4, 1, 2, 5]
}
创建一些与您的SVG元素(要重新排序)的1:1关系的z-indices数组。以下示例中使用的Z索引数组是ID,x和amp; y位置,半径等......
circles.data(zOrders[setOrderBy]);
然后,使用D3将z-indices绑定到该选择。
circles.sort(setOrder);
最后,调用D3.sort根据数据重新排序DOM中的元素。
[3,4,1,2,5]
Updating SVG Element Z-Index With D3
System.out.println("The book named " + Object.bookName);
移动/重新排序第3个圆圈(在原始HTML顺序中)为DOM中的第1个,第4个是第2名,第1名是第3名,依此类推...... 答案 3 :(得分:19)
您可以使用use。
<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>
<use xlink:href="#one" />
</svg>
绿色圆圈出现在顶部 jsFiddle
答案 4 :(得分:9)
svgs没有z-index。但是svg确定哪些元素在DOM中的最重要位置。因此,您可以删除Object并将其放在svg的末尾,使其成为“最后渲染”元素。然后,那个视觉呈现为“最顶层”。
使用jQuery:
function moveUp(thisObject){
thisObject.appendTo(thisObject.parents('svg>g'));
}
用法:
moveUp($('#myTopElement'));
使用D3.js:
d3.selection.prototype.moveUp = function() {
return this.each(function() {
this.parentNode.appendChild(this);
});
};
用法:
myTopElement.moveUp();
答案 5 :(得分:8)
如上所述,svgs按顺序呈现,并且不考虑z-index(现在)。也许只是将特定元素发送到其父元素的底部,以便它最后呈现。
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,则需要将该项目从其parentNode中删除。
function bringToTopofSVG(targetElement){
let parent = targetElement.ownerSVGElement;
parent.appendChild(targetElement);
}
SVG的一个很好的功能是每个元素都包含它的位置,无论它嵌套在哪个组中:+ 1:
答案 6 :(得分:7)
使用D3:
如果您想以相反的顺序将元素添加到数据使用:
>>> re.search(r'\d+\.\d+', 'hello Rs. 150.00').group()
'150.00'
>>> re.search(r'\d+\.\d+', 'hello Rs. 150.00 and some more text').group()
'150.00'
而不是.append
答案 7 :(得分:6)
使用D3:
如果要按顺序重新插入每个选定元素,作为其父级的最后一个子元素。
selection.raise()
答案 8 :(得分:5)
另一个解决方案是使用div,它使用zIndex来包含SVG元素。如下所示: https://stackoverflow.com/a/28904640/4552494
答案 9 :(得分:3)
截至本答复日期发布的清晰,快速,简便的解决方案并不令人满意。它们构建在SVG文档缺乏z顺序的错误陈述之上。图书馆也不是必需的。一行代码可以执行大多数操作来操作在x-y-z空间中移动2D对象的应用程序开发中可能需要的对象或对象组的z顺序。
在SVG文档碎片中肯定存在Z顺序
所谓的SVG文档片段是从基本节点类型SVGElement派生的元素树。 SVG文档片段的根节点是SVGSVGElement,它对应于HTML5 &lt; svg&gt; 标记。 SVGGElement对应&lt; g&gt; 标记,并允许聚合子代。
在CSS中使用SVGElement上的z-index属性会破坏SVG渲染模型。 W3C SVG Recommendation v1.1 2nd Edition的第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顺序操作。
没有造成混乱的正确答案
因为可以像SVGCircleElement或任何其他形状一样轻松地删除和插入SVGGElement(&lt; g&gt; 标记),所以可以使用Adobe产品和其他图形工具的典型图像层实现轻松使用SVGGElement。这个JavaScript本质上是一个 Move Below 命令。
parent.insertBefore(parent.removeChild(gRobot), gDoorway)
如果作为SVGGElement gRobot的子项绘制的机器人层位于作为SVGGElement gDoorway的子项绘制的门口之前,机器人现在位于门口后面,因为门口的z顺序现在是一个加上机器人的z顺序。
Move Above 命令几乎一样容易。
parent.insertBefore(parent.removeChild(gRobot), gDoorway.nextSibling())
想想a = a和b = b就能记住这一点。
insert after = move above
insert before = move below
让DOM处于与视图一致的状态
这个答案是正确的原因是因为它是最小和完整的,并且像Adobe产品的内部或其他精心设计的图形编辑器一样,使内部表示处于与渲染创建的视图一致的状态。
替代但有限的方法
另一种常用的方法是将CSS z-index与多个SVG文档片段(SVG标记)结合使用,除了底层之外的所有部分都具有大多数透明背景。同样,这会破坏SVG渲染模型的优雅,使得难以按z顺序向上或向下移动对象。
备注:强>
3.3渲染顺序SVG文档片段中的元素具有隐式绘制顺序,SVG文档中包含第一个元素 片段首先被“画”。后续元素被绘制 以前绘制元素的顶部。
3.4如何渲染组分组元素(如'g'元素(请参阅容器元素))具有生成临时的效果 单独的画布初始化为透明黑色到哪个孩子 元素被绘。完成组后,任何过滤器 为组创建的效果将应用于创建修改后的效果 临时画布。修改后的临时画布合成到 背景,考虑任何组级别的掩蔽和不透明度 小组上的设置。
答案 10 :(得分:3)
我们已经 2019 ,并且SVG仍不支持z-index
。
您可以在站点 SVG2 support in Mozilla 上看到z-index
的状态– 未实现。
您还可以在 Bug 360148 "Support the 'z-index' property on SVG elements" 网站上看到(报告:12年前)。
但是您可以在SVG中设置3种可能性:
element.appendChild(aChild);
parentNode.insertBefore(newNode, referenceNode);
targetElement.insertAdjacentElement(positionStr, newElement);
(在IE中不支持SVG)具有这三个功能。
var state = 0,
index = 100;
document.onclick = function(e)
{
if(e.target.getAttribute('class') == 'clickable')
{
var parent = e.target.parentNode;
if(state == 0)
parent.appendChild(e.target);
else if(state == 1)
parent.insertBefore(e.target, null); //null - adds it on the end
else if(state == 2)
parent.insertAdjacentElement('beforeend', e.target);
else
e.target.style.zIndex = index++;
}
};
if(!document.querySelector('svg').insertAdjacentElement)
{
var label = document.querySelectorAll('label')[2];
label.setAttribute('disabled','disabled');
label.style.color = '#aaa';
label.style.background = '#eee';
label.style.cursor = 'not-allowed';
label.title = 'This function is not supported in SVG for your browser.';
}
label{background:#cef;padding:5px;cursor:pointer}
.clickable{cursor:pointer}
With:
<label><input type="radio" name="check" onclick="state=0" checked/>appendChild()</label>
<label><input type="radio" name="check" onclick="state=1"/>insertBefore()</label><br><br>
<label><input type="radio" name="check" onclick="state=2"/>insertAdjacentElement()</label>
<label><input type="radio" name="check" onclick="state=3"/>Try it with z-index</label>
<br>
<svg width="150" height="150" viewBox="0 0 150 150">
<g stroke="none">
<rect id="i1" class="clickable" x="10" y="10" width="50" height="50" fill="#80f"/>
<rect id="i2" class="clickable" x="40" y="40" width="50" height="50" fill="#8f0"/>
<rect id="i3" class="clickable" x="70" y="70" width="50" height="50" fill="#08f"/>
</g>
</svg>
答案 11 :(得分:2)
将SVG元素推至最后,以使其z-index在顶部。在SVG中,没有称为z-index的属性。尝试在下面的javascript中将元素置于顶部。
var Target = document.getElementById(event.currentTarget.id);
var svg = document.getElementById("SVGEditor");
svg.insertBefore(Target, svg.lastChild.nextSibling);
目标:是我们需要将其放在首位的元素 svg:是元素的容器
答案 12 :(得分:0)
容易做到:
- (float)getFloatPartOfString:(NSString *)numstr {
NSScanner *scanner = [NSScanner scannerWithString:numstr];
int numerator = 0;
int denominator = 0;
float number = 0;
if ([scanner scanInt:&numerator]) && [scanner scanString:@"/" intoString:nil] && [scanner scanInt:&denominator] {
number = (float)numerator / (float)denominator;
} else {
NSLog(@"Didn't find integer / integer");
}
NSLog(@"%@ turns into %f", numstr, number);
return number;
}
function rebuildElementsOrder( selector, orderAttr, sortFnCallback ) {
let $items = $(selector);
let $cloned = $items.clone();
$cloned.sort(sortFnCallback != null ? sortFnCallback : function(a,b) {
let i0 = a.getAttribute(orderAttr)?parseInt(a.getAttribute(orderAttr)):0,
i1 = b.getAttribute(orderAttr)?parseInt(b.getAttribute(orderAttr)):0;
return i0 > i1?1:-1;
});
$items.each(function(i, e){
e.replaceWith($cloned[i]);
})
}
$('use[order]').click(function() {
rebuildElementsOrder('use[order]', 'order');
/* you can use z-index property for inline css declaration
** getComputedStyle always return "auto" in both Internal and External CSS decl [tested in chrome]
rebuildElementsOrder( 'use[order]', null, function(a, b) {
let i0 = a.style.zIndex?parseInt(a.style.zIndex):0,
i1 = b.style.zIndex?parseInt(b.style.zIndex):0;
return i0 > i1?1:-1;
});
*/
});
use[order] {
cursor: pointer;
}
答案 13 :(得分:0)
通过transform:TranslateZ移到最前面
警告:仅适用于FireFox
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 160 160" style="width:160px; height:160px;">
<g style="transform-style: preserve-3d;">
<g id="one" style="transform-style: preserve-3d;">
<circle fill="green" cx="100" cy="105" r="20" style="transform:TranslateZ(1px);"></circle>
</g>
<g id="two" style="transform-style: preserve-3d;">
<circle fill="orange" cx="100" cy="95" r="20"></circle>
</g>
</g>
</svg>