it-swarm.com.de

Wie verwende ich Z-Index in SVG-Elementen?

Ich benutze die Svg-Kreise in meinem Projekt wie folgt,

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

Und ich benutze den Z-Index im Tag g, um die ersten Elemente anzuzeigen. In meinem Projekt muss ich nur den Z-Index-Wert verwenden, aber ich kann den Z-Index nicht für meine SVG-Elemente verwenden. Ich habe viel gegoogelt, aber relativ nichts gefunden. Bitte helfen Sie mir, Z-Index in meinem SVG zu verwenden.

Hier ist das DEMO.

131
Karthi Keyan

Spezifikation

In der SVG-Spezifikation Version 1.1 basiert die Renderreihenfolge auf der Dokumentenreihenfolge:

first element -> "painted" first

Verweis auf die SVG 1.1. Spezifikation

.3 Renderreihenfolge

Elemente in einem SVG-Dokumentfragment haben eine implizite Zeichenreihenfolge, wobei die ersten Elemente im SVG-Dokumentfragment erhalten. " gemalt "zuerst . Nachfolgende Elemente werden über zuvor gemalte Elemente gezeichnet.


Lösung (sauberer-schneller)

Sie sollten den grünen Kreis als letztes zu zeichnendes Objekt einfügen. Tauschen Sie also die beiden Elemente aus.

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

Hier die Gabel deines jsFiddle .

Lösung (alternativ)

Das Tag use mit dem Attribut xlink:href und als Wert die ID des Elements. Denken Sie daran, dass dies möglicherweise nicht die beste Lösung ist, auch wenn das Ergebnis in Ordnung zu sein scheint. Mit etwas Zeit, hier der Link der Spezifikation SVG 1.1 "use" Element .

Zweck:

Um zu vermeiden, dass Autoren das referenzierte Dokument ändern müssen, um dem Stammelement eine ID hinzuzufügen.

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

Hinweise zu SVG 2

SVG 2-Spezifikation ist die nächste Hauptversion und unterstützt weiterhin die oben genannten Funktionen.

.4. Renderreihenfolge

Elemente in SVG werden in drei Dimensionen positioniert. Zusätzlich zu ihrer Position auf der x- und y-Achse des SVG-Ansichtsfensters werden SVG-Elemente auch auf der z-Achse positioniert. Die Position auf der Z-Achse definiert die Reihenfolge, in der sie gezeichnet werden .

Entlang der z-Achse werden Elemente in Stapelkontexten gruppiert.

.4.1. Erstellen eines Stapelkontexts in SVG

...

Stapelkontexte sind konzeptionelle Werkzeuge, mit denen die Reihenfolge beschrieben wird, in der Elemente beim Rendern des Dokuments übereinander gezeichnet werden müssen .

142
Maicolpt

Versuchen Sie, #one Und #two Zu invertieren. Schauen Sie sich diese Geige an: http://jsfiddle.net/hu2pk/3/

Update

In SVG wird der Z-Index durch die Reihenfolge definiert, in der das Element im Dokument angezeigt wird . Sie können diese Seite auch aufrufen, wenn Sie möchten: https://stackoverflow.com/a/482147/1932751

28
Lucas Willems

Wie bereits erwähnt, wird der Z-Index durch die Reihenfolge definiert, in der das Element im DOM angezeigt wird. Wenn es nicht möglich oder schwierig ist, HTML manuell neu zu ordnen, können Sie mit D3 SVG-Gruppen/-Objekte neu ordnen.

Verwenden Sie D3, um die DOM-Reihenfolge zu aktualisieren und die Z-Index-Funktionalität nachzuahmen

Aktualisieren des SVG-Element-Z-Index mit D

Auf der einfachsten Ebene (und wenn Sie für nichts anderes IDs verwenden) können Sie Element-IDs als Ersatz für den Z-Index verwenden und mit diesen neu anordnen. Darüber hinaus können Sie Ihrer Fantasie freien Lauf lassen.

Beispiele im Codeausschnitt

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>

Die Grundidee ist:

  1. Verwenden Sie D3, um die SVG-DOM-Elemente auszuwählen.

    var circles = d3.selectAll('circle')
    
  2. Erstellen Sie ein Array von Z-Indizes mit einer 1: 1-Beziehung zu Ihren SVG-Elementen (die Sie neu anordnen möchten). In den folgenden Beispielen verwendete Z-Index-Arrays sind IDs, X- und Y-Positionen, Radien usw.

    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. Verwenden Sie dann D3, um Ihre Z-Indizes an diese Auswahl zu binden.

    circles.data(zOrders[setOrderBy]);
    
  4. Zuletzt rufen Sie D3.sort auf, um die Elemente im DOM basierend auf den Daten neu anzuordnen.

    circles.sort(setOrder);
    

Beispiele

enter image description here

  • Sie können nach ID stapeln

enter image description here

  • Mit ganz links SVG an der Spitze

enter image description here

  • Kleinste Radien oben

enter image description here

  • Oder Geben Sie ein Array an, um den Z-Index für eine bestimmte Reihenfolge anzuwenden. In meinem Beispielcode ist das Array [3,4,1,2,5] verschiebt/ordnet den 3. Kreis (in der ursprünglichen HTML-Reihenfolge) als 1. im DOM, 4. als 2., 1. als 3. usw. an.

24
Steve Ladavich

Sie können verwenden verwenden.

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

Der grüne Kreis erscheint oben.
jsFiddle

20
Jose Rui Santos

Wie bereits erwähnt, rendern svgs in der richtigen Reihenfolge und berücksichtigen den Z-Index (vorerst) nicht. Senden Sie das betreffende Element möglicherweise einfach an den unteren Rand des übergeordneten Elements, damit es zuletzt gerendert wird.

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

Hat für mich gearbeitet.

Aktualisieren

Wenn Sie eine verschachtelte SVG-Datei haben, die Gruppen enthält, müssen Sie das Element aus dem übergeordneten Knoten entfernen.

function bringToTopofSVG(targetElement){
  let parent = targetElement.ownerSVGElement;
  parent.appendChild(targetElement);
}

Ein nettes Feature von SVGs ist, dass jedes Element seine Position enthält, unabhängig davon, in welcher Gruppe es verschachtelt ist: +1:

10
bumsoverboard

Es gibt keinen Z-Index für SVGs. Aber svg bestimmt, welche Ihrer Elemente durch ihre Position im DOM am obersten sind. Auf diese Weise können Sie das Objekt entfernen und an das Ende des SVGs setzen, wodurch es zum "zuletzt gerenderten" Element wird. Dieser wird dann optisch "topmost" gerendert.


sing jQuery:

function moveUp(thisObject){
    thisObject.appendTo(thisObject.parents('svg>g'));
}

verwendungszweck:

moveUp($('#myTopElement'));

Mit D3.js:

d3.selection.prototype.moveUp = function() {
    return this.each(function() {
        this.parentNode.appendChild(this);
    });
};

verwendungszweck:

myTopElement.moveUp();

9
Hafenkranich

Mit D3:

Wenn Sie das Element in umgekehrter Reihenfolge zu den Daten hinzufügen möchten, verwenden Sie:

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

Anstelle von .append

Hinzufügen eines Elements zum Anfang eines Gruppenelements

8
Nathan Hensher

Mit D3:

Wenn Sie jedes ausgewählte Element der Reihe nach als letztes untergeordnetes Element des übergeordneten Elements einfügen möchten.

selection.raise()
7
Diso

Eine andere Lösung wäre die Verwendung von divs, die zIndex verwenden, um die SVG-Elemente zu enthalten. Wie hier: https://stackoverflow.com/a/28904640/4552494

5
Roman Rekhler

Die zum Datum dieser Antwort veröffentlichten sauberen, schnellen und einfachen Lösungen sind unbefriedigend. Sie basieren auf der fehlerhaften Aussage, dass SVG-Dokumente nicht in der richtigen Reihenfolge vorliegen. Bibliotheken sind ebenfalls nicht erforderlich. Eine Codezeile kann die meisten Operationen ausführen, um die z-Reihenfolge von Objekten oder Objektgruppen zu ändern, die bei der Entwicklung einer App erforderlich sind, mit der 2D-Objekte in einem x-y-z-Raum verschoben werden.

Z-Reihenfolge ist in SVG-Dokumentfragmenten definitiv vorhanden

Was als SVG-Dokumentfragment bezeichnet wird, ist ein Baum von Elementen, die vom Basisknotentyp SVGElement abgeleitet sind. Der Stammknoten eines SVG-Dokumentfragments ist ein SVGSVGElement, das einem HTML5-Tag <svg> entspricht. Das SVGGElement entspricht dem Tag <g> und ermöglicht das Aggregieren von untergeordneten Elementen.

Ein Z-Index-Attribut für das SVGElement wie in CSS würde das SVG-Rendering-Modell zunichte machen. In den Abschnitten 3.3 und 3.4 der W3C-SVG-Empfehlung v1.1 (2nd Edition) wird angegeben, dass SVG-Dokumentfragmente (Bäume von Nachkommen eines SVGSVGElement) mithilfe einer sogenannten Tiefensuche des Baums gerendert werden . Dieses Schema ist in jeder Hinsicht eine z-Ordnung.

Z order ist eigentlich eine Abkürzung für Computer Vision, um die Notwendigkeit eines echten 3D-Renderings mit den Komplexitäten und Rechenanforderungen von Ray Tracing zu vermeiden. Die lineare Gleichung für den impliziten Z-Index von Elementen in einem SVG-Dokumentfragment.

z-index = z-index_of_svg_tag + depth_first_tree_index / tree_node_qty

Dies ist wichtig, denn wenn Sie einen Kreis, der sich unter einem Quadrat befand, nach oben verschieben möchten, fügen Sie einfach das Quadrat vor dem Kreis ein. Dies kann einfach in JavaScript erfolgen.

Unterstützende Methoden

SVGElement-Instanzen verfügen über zwei Methoden, die eine einfache und einfache Manipulation der z-Reihenfolge unterstützen.

  • parent.removeChild (child)
  • parent.insertBefore (child, childRef)

Die richtige Antwort, die kein Durcheinander verursacht

Da das SVGGElement ( <g> -Tag) genauso einfach entfernt und eingefügt werden kann wie ein SVGCircleElement oder jede andere für Adobe-Produkte und typische Form von Bildebenen andere Grafikwerkzeuge können mit dem SVGGElement problemlos implementiert werden. Dieses JavaScript ist im Wesentlichen ein Befehl zum Verschieben unter .

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

Wenn die Ebene eines Roboters, der als Kinder von SVGGElement gRobot gezeichnet wurde, vor der Tür war, die als Kinder von SVGGElement gDoorway gezeichnet wurde, befindet sich der Roboter jetzt hinter der Tür, da die z-Reihenfolge der Tür jetzt eins plus die z-Reihenfolge des Roboters ist.

Ein Befehl zum Verschieben nach oben ist fast genauso einfach.

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

Denken Sie nur an a = a und b = b, um sich daran zu erinnern.

insert after = move above
insert before = move below

Belassen des DOM in einem Zustand, der mit der Ansicht übereinstimmt

Diese Antwort ist richtig, weil sie minimal und vollständig ist und wie die Interna von Adobe-Produkten oder anderen gut gestalteten Grafikeditoren die interne Darstellung in einem Zustand belässt, der mit der durch das Rendern erstellten Ansicht konsistent ist.

Alternativer, aber begrenzter Ansatz

Ein anderer häufig verwendeter Ansatz ist die Verwendung des CSS-Z-Index in Verbindung mit mehreren SVG-Dokumentfragmenten (SVG-Tags) mit größtenteils transparentem Hintergrund in allen außer dem unteren. Dies beeinträchtigt wiederum die Eleganz des SVG-Rendering-Modells und macht es schwierig, Objekte in der z-Reihenfolge nach oben oder unten zu verschieben.


HINWEISE:

  1. ( https://www.w3.org/TR/SVG/render.html v 1.1, 2. Ausgabe, 16. August 2011)

    3.3 Renderreihenfolge Elemente in einem SVG-Dokumentfragment haben eine implizite Zeichenreihenfolge, wobei die ersten Elemente im SVG-Dokumentfragment zuerst "gezeichnet" werden. Nachfolgende Elemente werden über zuvor gemalte Elemente gezeichnet.

    3.4 Wie Gruppen gerendert werden Durch Gruppieren von Elementen wie dem Element 'g' (siehe Containerelemente) wird eine temporäre separate Leinwand erzeugt, die in transparentem Schwarz initialisiert wird und auf der untergeordnete Elemente gezeichnet werden. Nach Abschluss der Gruppe werden alle für die Gruppe angegebenen Filtereffekte angewendet, um eine geänderte temporäre Zeichenfläche zu erstellen. Die geänderte temporäre Zeichenfläche wird unter Berücksichtigung der Maskierungs- und Deckkrafteinstellungen auf Gruppenebene in den Hintergrund eingefügt.

4
Douglas Daseeco

Wir haben bereits 2019 und z-index Wird in SVG immer noch nicht unterstützt.

Sie können auf der Seite SVG2-Unterstützung in Mozilla sehen, dass der Status für z-index - Nicht implementiert.

Sie können auch auf der Website sehen Bug 360148 "Unterstützen Sie die 'Z-Index'-Eigenschaft für SVG-Elemente" (Gemeldet: vor 12 Jahren).

In SVG haben Sie jedoch drei Möglichkeiten, dies festzulegen:

  1. Mit element.appendChild(aChild);
  2. Mit parentNode.insertBefore(newNode, referenceNode);
  3. Mit targetElement.insertAdjacentElement(positionStr, newElement); (Keine Unterstützung in IE für SVG)

Interaktives Demo-Beispiel

Mit all diesen 3 Funktionen.

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

Schieben Sie das SVG-Element zum Letzten, damit der Z-Index oben ist. In SVG gibt es keine Eigenschaft namens z-index. Versuchen Sie unten Javascript, um das Element nach oben zu bringen.

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

Ziel: Ist ein Element, für das wir es nach oben bringen müssen. Svg: Ist der Container mit Elementen

2

es ist einfach zu tun:

  1. Klon Ihre Artikel
  2. sortieren geklonte Objekte
  3. Ersetzen Elemente durch geklont
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