JavaScript로 SVG <g> 요소의 Z 인덱스 / 레이어를 변경할 수 있습니까?


85

몇 가지 합성 모양 ( <g>) 이 있다고 가정 해 보겠습니다 . 나는 그것들을 클릭하고 드래그 할 수 있기를 원하지만, 지금 드래그하고있는 하나가 Z 순서에서 다른 하나의 맨 위에 있기를 원합니다. 그래서 다른 하나 위로 드래그하면 다른 하나가 하나는 가려 져야합니다.



답변:


113

SVG의 Z 인덱스는 요소가 문서에 나타나는 순서로 정의됩니다. 특정 모양을 맨 위로 가져 오려면 요소 순서를 변경해야합니다.


1
문서 끝에있는 @theonlygusti 요소가 맨 위에 있습니다. jQuery를 사용하는 경우 다음과 같은 것을 사용할 수 있어야합니다.$('#thing-i-want-on-top').appendTo('#my-svg');
Adam Bradley

따라서 기본적으로 마우스를 올려 놓을 때 모양을 맨 위 (z 축)에 띄울 수있는 방법이 없습니다…?
chharvey

jQuery는 SVG 경로의 순서 변경을 지원하지 않습니다.
Senthe

4
@chharvey, 순서를 다시 지정하여 맨 위에 표시 할 수 있습니다. 여기에 우아한 예는 다음과 같습니다 codepen.io/osublake/pen/YXoEQe
프레이저 Kirkman

36

트리에서 요소를 이동하는 것에 대한 대안은 원하는 z 순서를 제공하도록 속성 <use>을 변경하는 요소 를 사용 xlink:href하는 것입니다.

다음은 일부 모양에 애니메이션을 적용하려는 맥락에서이 주제를 논의하는 svg- 개발자 메일 링리스트 의 오래된 스레드 입니다.

최신 정보:

<svg xmlns="http://www.w3.org/2000/svg" 
     xmlns:xlink="http://www.w3.org/1999/xlink"
     style="width:100%; height: 100%">
    <circle id="c1" cx="50" cy="50" r="40" fill="lime" />
    <rect id="r1" x="4" y="20" width="200" height="50" fill="cyan" />
    <circle id="c2" cx="70" cy="70" r="50" fill="fuchsia" />
    <use id="use" xlink:href="#c1" />
</svg>

이 예에서 <use> 요소는 마지막 요소이므로 가장 앞쪽 요소가됩니다. xlink:href속성 을 변경하여 맨 앞에있는 다른 요소를 선택할 수 있습니다 . 위의 예에서으로 원을 선택 id="c1"하여 최상위 요소로 나타납니다.

바이올린 참조 .


1
이 답변은 예제 또는 해당 메일 링리스트의 정보 (게이트 됨)에서 훨씬 더 유용합니다.
Kyeotic 2014 년

3
작동하지만 적절하게 사용하십시오. 당신이 번역, <사용>을 사용하는 경우 그들에 대해 아무 생각이 없습니다
요헨 Bedersdorfer

@JochenBedersdorfer가 무슨 뜻인지 잘 모르겠습니다. 번역이 z 주문과 어떤 관련이 있습니까?
Erik Dahlström

그것에 대해 명확하지 않았습니다. 변형과 함께 중첩 된 <g>-태그를 사용하는 경우 getTransformToElement (..);를 사용하여 좌표를 변환해야합니다. (SVG 문서 참조)
Jochen Bedersdorfer 2015

3
xlink:href더 이상 사용되지 않습니다. 이제 그냥href
osvein

22

이것은 오래된 질문이지만 ...

FireFox (7+) 및 Chrome (14+)에서는 svg_element를 맨 위로 가져올 수 있습니다. 이것은 완전한 z 축 제어의 자유를 제공하지는 않지만 아무것도없는 것보다 낫습니다.)

해당 요소를 다시 추가하십시오.

var svg = doc.createElemNS('svg');
var circle = doc.createElemNS('circle');
var line = doc.createElemNS('line');

svg.appendChild(circle); // appends it
svg.appendChild(line);   // appends it over circle
svg.appendChild(circle); // redraws it over line now

나는 그것이 오류 같은 것을 던질 것이라고 생각했습니다.

appendChild == 자체 교체 == 다시 그리기


3
전혀 오류가 아닙니다. appendChild먼저 이전 부모 (있는 경우)에서 새 부모와 동일하더라도 제거하고 새 부모의 자식 목록에 추가합니다.
Potatoswatter

5

언급되지 않은 또 다른 해결책은 각 svg 항목 / 항목 집합을 div에 넣는 것입니다. div의 Z- 색인을 쉽게 변경할 수 있습니다.

Fiddle : 컨테이너 용 Z- 인덱스로 SVG 요소 순환

... 버튼을 눌러 해당 요소를 앞으로 밀어냅니다. (전체 세트를 다시 칠하고 1 개의 요소를 앞으로 밀지 만 허용 된 솔루션에서와 같이 원래 순서를 유지)

상대적인 z 인덱스가 있으면 매우 좋을 것입니다.

stackOverflow가 jsfiddle의 링크 인 경우 코드를 넣어달라고합니다.




3

SVG렌더링의 "페인터 모델"을 사용합니다. 페인트는 출력 장치에 연속 작업으로 적용되어 각 작업이 출력 장치의 일부 영역에 페인트됩니다. 이 지역은 이전에 그려진 영역을 중첩 할 때 새 페인트는 부분적으로 또는 완전히 됐지 모호 이 링크를


3

SVG에서 더 큰 Z 인덱스를 얻으려면 DOM 트리에서 요소를 아래로 이동해야합니다. jQuery를 사용하여 SVG 요소를 선택하고 제거하고 원하는 위치에 다시 추가 할 수 있습니다.

$('g.element').remove().appendTo('svg');

2

Sam의 대답에 대한 Adam Bradley의 의견은 정확히 정확했습니다. CSS가 아닌 jQuery를 사용하지만 그는 이렇게 말했습니다.

$('#thing-i-want-on-top').appendTo('#my-svg');

그러나 내가 만드는 것을 위해 SVG 경로가 호버시 다른 경로 위에 있어야하지만 여전히 내 SVG 텍스트 아래에 있어야했습니다. 그래서 여기에 내가 생각 해낸 것이 있습니다.

$('#thing-i-want-on-top').insertBefore('#id-for-svg-text');

appendTo 및 insertBefore 모두 요소를 새 위치로 이동하여 원하는대로 SVG 요소의 깊이를 변경할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.