[javascript] svg 요소에서 z-index를 사용하는 방법은 무엇입니까?

이 프로젝트에서 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 1.1을 참조하십시오 . 사양

3.3 렌더링 순서

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 사양 은 다음 주요 릴리스이며 위의 기능을 계속 지원합니다.

3.4. 렌더링 순서

SVG의 요소는 3 차원으로 배치됩니다. SVG 뷰포트의 x 및 y 축에서의 위치 외에 SVG 요소도 z 축에 있습니다. z 축의 위치 는 페인트 순서를 정의합니다 .

z 축을 따라 요소는 스태킹 컨텍스트로 그룹화됩니다.

3.4.1. SVG에서 스태킹 컨텍스트 설정

스태킹 컨텍스트는 문서가 렌더링 될 때 요소가 다른 요소 위에 그려 져야하는 순서설명하는 데 사용되는 개념적 도구입니다 .


답변

다른 사람들이 말했듯이 z-index는 요소가 DOM에 나타나는 순서로 정의됩니다. HTML을 수동으로 재정렬하는 것이 옵션이 아니거나 어려운 경우 D3을 사용하여 SVG 그룹 / 객체를 재정렬 할 수 있습니다.

D3을 사용하여 DOM 순서 업데이트 및 Z- 인덱스 기능 모방

D3를 사용하여 SVG 요소 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>

기본 아이디어는 다음과 같습니다.

  1. D3을 사용하여 SVG DOM 요소를 선택하십시오.

    var circles = d3.selectAll('circle')
  2. 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]
    }
    
  3. 그런 다음 D3을 사용하여 z- 표시를 해당 선택에 바인딩하십시오.

    circles.data(zOrders[setOrderBy]);
  4. 마지막으로 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();