207

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

これがデモです。

4

16 に答える 16

207

仕様

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のフォークがあります。

解決策(代替)

use属性を持つタグxlink:href( SVG 2hrefのみ) と値として要素の 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 でスタック コンテキストを確立する

...

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

于 2014-08-14T07:23:10.710 に答える
18

説明したように、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 の優れた機能は、ネストされているグループに関係なく、各要素にその場所が含まれていることです:+1:

于 2017-11-15T03:25:18.683 に答える
8

D3 の使用:

逆の順序で要素をデータに追加する場合は、次を使用します。

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

.append の代わりに

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

于 2016-04-22T11:29:19.087 に答える
6

この回答の日付の時点で投稿された、クリーンで高速で簡単なソリューションは満足のいくものではありません。それらは、SVG 文書には z オーダーがないという欠陥のあるステートメントに基づいて構築されています。ライブラリも必要ありません。xyz 空間で 2D オブジェクトを移動するアプリの開発で必要となる可能性がある、オブジェクトまたはオブジェクトのグループの z オーダーを操作するためのほとんどの操作を 1 行のコードで実行できます。

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

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

CSS のように SVGElement に z-index 属性を設定すると、SVG レンダリング モデルが無効になります。W3C SVG 勧告 v1.1 第 2 版のセクション 3.3 および 3.4 では、SVG ドキュメント フラグメント (SVGSVGElement から派生したツリー) は、ツリーの深さ優先検索と呼ばれるものを使用してレンダリングされると述べられています。そのスキームは、用語のあらゆる意味で 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(子、子参照)

混乱しない正解

SVGGElement ( <g>タグ) は、SVGCircleElement やその他の図形と同じように簡単に削除および挿入できるため、SVGGElement を使用して、Adobe 製品やその他のグラフィック ツールに典型的なイメージ レイヤーを簡単に実装できます。この 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 を残す

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

代替的だが限定的なアプローチ

一般的に使用される別のアプローチは、CSS z-index を複数の SVG ドキュメント フラグメント (SVG タグ) と組み合わせて使用​​することであり、下の部分を除くほとんどの背景が透明です。繰り返しになりますが、これは 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' 要素 (コンテナ要素を参照) などのグループ化要素には、子要素が描画される透明な黒に初期化された一時的な別のキャンバスを生成する効果があります。グループが完了すると、グループに指定されたフィルター効果が適用され、変更された一時的なキャンバスが作成されます。変更された一時キャンバスは、グループのグループ レベルのマスキングと不透明度の設定を考慮して、背景に合成されます。

于 2018-06-12T12:52:30.973 に答える
5

別の解決策は、zIndex を使用して SVG 要素を含む div を使用することです

于 2015-03-06T18:15:41.993 に答える
1

これは、z-index と SVG に関する Google の検索結果のトップです。すべての回答を読んだ後、そのうちのいくつかは非常に優れていましたが、私はまだ混乱していました.

私のような新人のために、9 年後の 2022 年現在の概要を以下に示します。

SVG で z-index を使用することはできません。

SVG では、z-index は要素がドキュメントに表示される順序によって定義されます。

ユーザーの一番上または近くに何かを表示したい場合は、最後に描画します。 ソース

SVG 2 は z-index をサポートできますが、決してサポートされない可能性があります

SVG 2 は、その機能やその他の機能を実装するための提案ですが、前進しないリスクがあります。

SVG 2 は 2016 年に勧告候補段階に達し、2018 年に改訂され、最新のドラフトが 2021 年 6 月 8 日にリリースされました。ソース

しかし、それはあまり支持されておらず、それに取り組んでいる人はほとんどいません。ソースだから、これを待って息を止めないでください。

D3 を使用できますが、おそらくすべきではありません

データを視覚化するために一般的に使用されるD3は、z-index をバインドしてからソートすることで z-index をサポートしますが、これは大規模で複雑なライブラリであり、特定の SVG をスタックの上に表示したいだけの場合は最善の策ではない可能性があります。

于 2022-01-24T21:13:38.857 に答える
0

それを行うのは簡単です:

  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>

于 2019-04-05T00:54:11.520 に答える