web-dev-qa-db-ja.com

svg要素でz-indexを使用する方法

私は自分のプロジェクトでこのように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値のみを使用する必要がありますが、s-vg要素にz-indexを使用することはできません。私はたくさんグーグルしましたが、比較的なにも見つけられませんでした。だから私のsvgでz-indexを使うのを手伝ってください。

これが デモです。

127
karthik

仕様

SVG仕様書バージョン1.1では、レンダリングの順序は文書の順序に基づいています。

first element -> "painted" first

SVG 1.1への参照。仕様

3.3レンダリング順

SVGドキュメントフラグメント内の要素は暗黙の描画順序を持ち、 最初の要素 はSVGドキュメントフラグメント内の を「最初に描画」します 後続の要素は、以前に描画された要素の上に描画されます。


解決策(より速い)

あなたは描かれるべき最新のオブジェクトとして緑色の円を置くべきです。だから2つの要素を交換してください。

<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 のフォークです。

解決策(代替)

属性xlink:hrefおよび値としての要素のIDを持つタグuse。たとえ結果がうまくいったとしても最善の解決策ではないかもしれないことを覚えておいてください。少し時間がかかりますが、ここでは仕様 SVG 1.1のリンクに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でスタッキングコンテキストを確立する

...

スタッキングコンテキストは、 要素を重ねて描画する順序を記述するための概念的なツールです。 ドキュメントがレンダリングされるとき...

137
Maicolpt

#one#twoを反転させてみてください。このフィドルをご覧ください。 http://jsfiddle.net/hu2pk/3/

Update

SVGでは、z-indexは、要素がドキュメント内に現れる順番で定義されます。あなたが望むならあなたもこのページを見てみることができます。 https://stackoverflow.com/a/482147/1932751

28
Lucas Willems

他の人が言っているように、z-indexは要素がDOMに現れる順番によって定義されます。手動でhtmlを並べ替えることが選択肢にならない、または難しい場合は、D3を使用してSVGグループ/オブジェクトを並べ替えることができます。

D3を使用してDOMの順序を更新し、Z-Index機能を模倣する

D3によるSVG要素Zインデックスの更新

最も基本的なレベルでは(そして、他にIDを使用していない場合は)、z-indexの代わりとしてエレメントIDを使用して、それらを並べ替えることができます。それを超えてあなたはほとんどあなたの想像力を暴走させることができます。

コードスニペットの例

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. SVG DOM要素を選択するにはD3を使います。

    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);
    

enter image description here

  • IDでスタックできます

enter image description here

  • 一番左のSVGを上にして

enter image description here

  • 一番上の最小半径

enter image description here

  • または、特定の順序付けにz-indexを適用するための配列を指定します。私のサンプルコードでは、配列[3,4,1,2,5]は3番目の円を元のHTML順序で移動/並べ替え、DOMで1、4で2、1で3番目など.

23
Steve Ladavich

あなたは se を使うことができます。

<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

20
Jose Rui Santos

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();

9
Hafenkranich

説明したように、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の優れた特徴は、どのグループにネストされているかにかかわらず、各要素にその位置が含まれることです。

8
bumsoverboard

D3を使う:

データと逆の順序で要素を追加したい場合は、次のようにします。

.insert('g', ":first-child")

.appendの代わりに

グループ要素の先頭に要素を追加する

8
Nathan Hensher

D3を使う:

選択した各要素をその親の最後の子として順番に再挿入する場合。

selection.raise()
7
Diso

別の解決策はSVG要素を含めるためにzIndexを使用するdivを使用することです。ここにあります。 https://stackoverflow.com/a/28904640/4552494

5
Roman Rekhler

この回答の日付の時点で掲載されている、クリーンで速く、そして簡単な解決策は満足できるものではありません。それらはSVGドキュメントがzオーダーを欠いているという欠陥のあるステートメントの上に構築されています。図書館も必要ありません。 1行のコードでほとんどの操作を実行して、2Dオブジェクトをx-y-z空間内で移動させるアプリケーションの開発に必要なオブジェクトまたはオブジェクトのグループのzオーダーを操作できます。

ZオーダーはSVGドキュメントフラグメントに必ず存在します

SVGドキュメントフラグメントと呼ばれるものは、ベースノードタイプSVGElementから派生した要素のツリーです。 SVGドキュメントフラグメントのルートノードはSVGSVGElementです。これはHTML5<svg>タグに対応します。 SVGGElementは<g>タグに対応し、子の集約を許可します。

CSSのようにSVGElementにz-index属性を設定すると、SVGレンダリングモデルが無効になります。 W3C SVG勧告v1.1第2版の3.3節と3.4節では、SVG文書の断片(SVGSVGE要素からの子孫の木)は、いわゆる深さ優先探索を使ってレンダリングされると述べていますその方式は、用語のあらゆる意味でzオーダーです。

Zオーダーは実際にはレイトレーシングの複雑さと計算要求を伴う真の3Dレンダリングの必要性を避けるためのコンピュータビジョンショートカットです。 SVGドキュメントフラグメント内の要素の暗黙のzインデックスの線形方程式。

z-index = z-index_of_svg_tag + depth_first_tree_index / tree_node_qty

正方形の下にある円をその上に移動する場合は、円の前に正方形を挿入するだけなので、これは重要です。これはJavaScriptで簡単に行えます。

補助方法

SVGElementインスタンスには、単純で簡単なzオーダー操作をサポートする2つのメソッドがあります。

  • parent.removeChild(子)
  • parent.insertBefore(child、childRef)

混乱を引き起こさない正しい答え

SVGGElement(<g>タグ)は、SVGCircleElementや他の図形と同じくらい簡単に削除および挿入できるため、アドビ製品の典型的なイメージレイヤーやSVGGElementを使用すると、他のグラフィックツールを簡単に実装できます。このJavaScriptは基本的に下へ移動コマンドです。

parent.insertBefore(parent.removeChild(gRobot), gDoorway)

SVGGElement gRobotの子として描画されたロボットのレイヤーがSVGGElement gDoorwayの子として描画された出入口の前にある場合、出入口のzオーダーはロボットのzオーダーに1を加えたものになります。

上へ移動コマンドはほとんど同じです。

parent.insertBefore(parent.removeChild(gRobot), gDoorway.nextSibling())

これを覚えておくには、a = aとb = bと考えてください。

insert after = move above
insert before = move below

ビューと一貫した状態にDOMを残す

この答えが正しい理由は、それが最小限かつ完全であり、アドビ製品の内部や他のよく設計されたグラフィックエディタのように、レンダリングによって作成されたビューと一致する状態で内部表現を残すためです。

代替的だが制限されたアプローチ

一般的に使用されているもう1つのアプローチは、一番下のもの以外はほとんど透明な背景を持つ複数のSVGドキュメントフラグメント(SVGタグ)と共にCSS z-indexを使用することです。繰り返しますが、これはSVGレンダリングモデルの優雅さを損ない、オブジェクトをzオーダーで上下に動かすのを難しくします。


注:

  1. https://www.w3.org/TR/SVG/render.html v 1.1、第2版、2011年8月16日)

    3.3レンダリング順序SVGドキュメントフラグメントの要素は暗黙の描画順序を持ち、SVGドキュメントフラグメントの最初の要素は最初に「ペイント」されます。後続の要素は、以前に描画された要素の上に描画されます。

    3.4グループのレンダリング方法 'g'要素(コンテナ要素を参照)などのグループ化要素には、子要素が描画される透明な黒に初期化された一時的な個別のキャンバスを作成する効果があります。グループが完成すると、そのグループに指定されているフィルタ効果が適用されて、変更された一時的なキャンバスが作成されます。グループ上のグループレベルのマスキングと不透明度の設定を考慮して、変更された一時キャンバスが背景に合成されます。

4
Douglas Daseeco

私たちはすでに2019を持っていて、z-indexはまだSVGではサポートされていません。

あなたはサイト上で見ることができますMozillaでのSVG2サポートz-indexのための状態 - 実装されていない.

サイトでも見ることができますバグ360148:SVG要素の 'z-index'プロパティをサポートする(報告: 12年前).

しかし、それを設定するためにSVGには3つの可能性があります。

  1. element.appendChild(aChild);
  2. parentNode.insertBefore(newNode, referenceNode);
  3. WithtargetElement.insertAdjacentElement(positionStr, newElement);(SVGのIEではサポートされていません)

対話型デモの例

この3つの機能すべてを使って。

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>
4
Bharata

SVG要素を最後まで押し、そのzインデックスが一番上になるようにします。 SVGでは、z-indexというプロパティはありません。要素を上に移動するには、JavaScriptの下で試してください。

var Target = document.getElementById(event.currentTarget.id);
var svg = document.getElementById("SVGEditor");
svg.insertBefore(Target, svg.lastChild.nextSibling);

Target:一番上に持ってくる必要がある要素ですsvg:要素のコンテナです

2

それをするのは簡単:

  1. クローンあなたの商品
  2. ソートクローンアイテム
  3. 置換項目をクローンで
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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="keybContainer" viewBox="0 0 150 150" xml:space="preserve">
<defs>
    <symbol id="sym-cr" preserveAspectRatio="xMidYMid meet" viewBox="0 0 60 60">
        <circle cx="30" cy="30" r="30" />
        <text x="30" y="30" text-anchor="middle" font-size="0.45em" fill="white">
            <tspan dy="0.2em">Click to reorder</tspan>
        </text>
    </symbol>
</defs>
    <use order="1" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="0" y="0" width="60" height="60" style="fill: #ff9700; z-index: 1;"></use>
    <use order="4" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="50" y="20" width="50" height="50" style="fill: #0D47A1; z-index: 4;"></use>
    <use order="5" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="15" y="30" width="50" height="40" style="fill: #9E9E9E; z-index: 5;"></use>
    <use order="3" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="25" y="30" width="80" height="80" style="fill: #D1E163; z-index: 3;"></use>
    <use order="2" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="30" y="0" width="50" height="70" style="fill: #00BCD4; z-index: 2;"></use>
    <use order="0" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#sym-cr" x="5" y="5" width="100" height="100" style="fill: #E91E63; z-index: 0;"></use>
</svg>
0
tdjprog