이 프로젝트에서 svg circle을 사용하고 있습니다.
<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 값만 사용해야하지만 svg 요소에 z-index를 사용할 수 없습니다. 나는 많은 구글 검색을했지만 상대적으로 아무것도 찾지 못했습니다. 그래서 내 svg에서 z-index를 사용하도록 도와주세요.
여기 데모가 있습니다.
답변
사양
SVG 사양 버전 1.1에서 렌더링 순서는 문서 순서를 기반으로합니다.
first element -> "painted" first
SVG 문서 조각의 요소는 암묵적인 그리기 순서를 가지며 SVG 문서 조각의 첫 번째 요소 는 “페인트” 됩니다. 후속 요소는 이전에 페인트 한 요소 위에 페인트됩니다.
솔루션 (보다 빠르고 빠름)
녹색 원은 가장 최근에 그릴 객체로 놓아야합니다. 따라서 두 요소를 바꾸십시오.
<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>
여기 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>
SVG 2에 대한 참고 사항
SVG 2 사양 은 다음 주요 릴리스이며 위의 기능을 계속 지원합니다.
SVG의 요소는 3 차원으로 배치됩니다. SVG 뷰포트의 x 및 y 축에서의 위치 외에 SVG 요소도 z 축에 있습니다. z 축의 위치 는 페인트 순서를 정의합니다 .
z 축을 따라 요소는 스태킹 컨텍스트로 그룹화됩니다.
…
스태킹 컨텍스트는 문서가 렌더링 될 때 요소가 다른 요소 위에 그려 져야하는 순서 를 설명하는 데 사용되는 개념적 도구입니다 .
답변
다른 사람들이 말했듯이 z-index는 요소가 DOM에 나타나는 순서로 정의됩니다. HTML을 수동으로 재정렬하는 것이 옵션이 아니거나 어려운 경우 D3을 사용하여 SVG 그룹 / 객체를 재정렬 할 수 있습니다.
D3을 사용하여 DOM 순서 업데이트 및 Z- 인덱스 기능 모방
가장 기본적인 수준에서 (그리고 다른 용도로 ID를 사용하지 않는 경우) 요소 ID를 z- 인덱스의 독립형으로 사용하고 다시 정렬 할 수 있습니다. 그 너머로 상상력을 크게 발휘할 수 있습니다.
코드 스 니펫의 예
var circles = d3.selectAll('circle')
var label = d3.select('svg').append('text')
.attr('transform', 'translate(' + [5,100] + ')')
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]
}
var setOrderBy = 'IDs';
var setOrder = d3.descending;
label.text(setOrderBy);
circles.data(zOrders[setOrderBy])
circles.sort(setOrder);
<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>
기본 아이디어는 다음과 같습니다.
-
D3을 사용하여 SVG DOM 요소를 선택하십시오.
var circles = d3.selectAll('circle')
-
SVG 요소와의 1 : 1 관계로 재정렬하려는 일부 z- 인디언스 배열을 만듭니다. 아래 예에서 사용 된 Z- 인덱스 배열은 ID, x & y 위치, 반지름 등입니다.
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] }
-
그런 다음 D3을 사용하여 z- 표시를 해당 선택에 바인딩하십시오.
circles.data(zOrders[setOrderBy]);
-
마지막으로 D3.sort를 호출하여 데이터를 기반으로 DOM의 요소를 재정렬합니다.
circles.sort(setOrder);
예
- ID로 쌓을 수 있습니다
- 가장 왼쪽에 SVG가있는 상태
- 가장 작은 반지름
- 또는 특정 순서에 대해 z-index를 적용 할 배열을 지정하십시오. 예제 코드에서 배열
[3,4,1,2,5]
은 DOM에서 1 번째, 4 번째에서 2 번째, 1 번째에서 3 번째로 (원래 HTML 순서로) 3 번째 원을 이동 / 재주문합니다. , 등등…
답변
반전을 시도 #one
하고 #two
. 이 바이올린을 살펴보십시오 : http://jsfiddle.net/hu2pk/3/
Update
SVG에서 z-index는 요소가 문서에 나타나는 순서로 정의됩니다 . 원하는 경우이 페이지를 볼 수도 있습니다 : https : //.com/a/482147/1932751
답변
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
답변
논의한 바와 같이 svgs는 순서대로 렌더링되며 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가있는 경우 항목을 parentNode에서 가져와야합니다.
function bringToTopofSVG(targetElement){
let parent = targetElement.ownerSVGElement;
parent.appendChild(targetElement);
}
SVG의 좋은 기능은 각 요소가 어떤 그룹에 중첩되어 있는지에 관계없이 위치를 포함한다는 것입니다.
답변
D3 사용 :
선택한 각 요소를 부모의 마지막 자식으로 순서대로 다시 삽입합니다.
selection.raise()
답변
svgs에 대한 z- 인덱스가 없습니다. 그러나 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();