web-dev-qa-db-ja.com

JavaScriptを使用して、SVG <g>要素のZインデックス/レイヤーを変更できますか?

いくつかの複合形状(<g>)。私はそれらをクリックしてドラッグできるようにしたいのですが、私がたまたまドラッグしているものを、Zオーダーでもう一方のトップの上に置きたいので、もう一方の上にドラッグすると、食されるべきです。

81
Corey Trager

SVGのZインデックスは、ドキュメントに要素が表示される順序で定義されます。特定の形状を一番上にしたい場合は、要素の順序を変更する必要があります。

108
Sam

ツリー内の要素を移動する代わりに、<use>属性を変更するxlink:href要素を使用して、必要なz順序を提供することもできます。

Svg-developersメーリングリストの 古いスレッド は、いくつかの形状をアニメーション化したいというコンテキストでこのトピックを議論しています。

更新:

<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"が付いた円を選択しました。これにより、一番上の要素として表示されます。

fiddle を参照してください。

32
Erik Dahlström

これは古い質問ですが、...

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 ==自分自身を置き換える==再描画

21
CoR

言及されていない別の解決策は、各svgアイテム/アイテムのセットをdivに入れることです。 divのz-indexを簡単に変更できます。

フィドル:コンテナーのz-indexを使用したSVG要素のサイクル

...ボタンを押して、その要素を前面に「プッシュ」します。 (セット全体を再描画し、1つの要素を前に押しますが、受け入れられたソリューションのように元の順序を維持します)

相対zインデックスがあると非常に便利です...

stackOverflowは、jsfiddleからのリンクである場合、コードを配置することを望んでいますか?...

var orderArray=[0,1,2];
var divArray = document.querySelectorAll('.shape');
var buttonArray = document.querySelectorAll('.button');

for(var i=0;i<buttonArray.length;i++){
    buttonArray[i].onclick=function(){
        var localI = i;
        return function(){clickHandler(orderArray.indexOf(localI));};
    }();
}


function clickHandler(divIndex) {
     orderArray.Push(orderArray.splice(divIndex, 1)[0]);
    orderDivs();
}

function orderDivs(){
    for(var i=0;i<orderArray.length;i++){
       divArray[orderArray[i]].style.zIndex=i;        
    }
}
svg {
    width: 100%;
    height: 100%;
    stroke: black;
    stroke-width:2px;
    pointer-events: all;
}
div{
    position:absolute;
}
div.button{
    top:55%;
    height:5%;
    width:15%;
    border-style: outset;
    cursor:pointer;
    text-align: center;
    background:rgb(175, 175, 234);
    
}
div.button:hover{
    border-style: inset;
    background:yellow;
    
}
div.button.first{
    left:0%;
}
div.button.second{
    left:20%;
}
div.button.third{
    left:40%;
}
<div class="shape">
    <svg>
    <circle cx="50" cy="50" r="40" fill="Lime" />
    </svg>
</div>
<div class="shape">
    <svg>
        <rect x="4" y="20" width="200" height="50" fill="cyan" />
    </svg>
</div>
<div class="shape">
    <svg>
        <circle cx="70" cy="70" r="50" fill="Fuchsia" />
    </svg>
</div>

<div class='button first'>Lime</div>
<div class='button second'>cyan</div>
<div class='button third'>Fuchsia</div>
5
Roman Rekhler

svg.jsライブラリ を使用する場合、「。front()」コマンドを使用して、任意の要素を最上部に移動できます。

4

はい、順序はどのオブジェクトが他のオブジェクトの前にあるかを指定するものです。順序を操作するには、DOMについて移動する必要があります。 https://www.w3.org/TR/SVG/render.html#RenderingOrder のSVG wikiにこの良い例があります

4
Kelly Anderson

SVGは、レンダリングの「ペインターモデル」を使用します。ペイントは、各操作が出力デバイスの一部の領域にペイントされるように、連続操作で出力デバイスに適用されます。領域が以前にペイントされた領域と重なると、新しいペイントは部分的にまたは完全に古いものを覆い隠します。 リンクへのリンク

3
Ishank

SVGでは、より大きなZインデックスを取得するには、DOMツリー内で要素を下に移動する必要があります。これを行うには、jQueryを使用し、SVG要素を選択して削除し、必要な位置に再度追加します。

$('g.element').remove().appendTo('svg');
2
Agu Dondo

サムの答えに対するアダムブラッドリーのコメントは、まさに正解でした。 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要素の深さを自由に変更できるようにします。

1
FiSH GRAPHICS