Kann ich mit JavaScript den Z-Index / die Ebene eines SVG <g> -Elements ändern?


85

Angenommen, ich habe ein paar zusammengesetzte Formen ( <g>). Ich möchte in der Lage sein, sie anzuklicken und zu ziehen, aber ich möchte, dass der, den ich gerade ziehe, in der Z-Reihenfolge oben auf dem anderen liegt, so dass, wenn ich ihn über den ANDEREN ziehe, der andere man sollte in den Schatten gestellt werden.


siehe hier .
Eliran Malka

Antworten:


113

Der Z-Index in SVG wird durch die Reihenfolge definiert, in der die Elemente im Dokument angezeigt werden. Sie müssen die Elementreihenfolge ändern, wenn Sie eine bestimmte Form nach oben bringen möchten.


1
@theonlygusti Elemente am Ende des Dokuments befinden sich oben. Wenn Sie jQuery verwenden, sollten Sie in der Lage sein, etwas wie$('#thing-i-want-on-top').appendTo('#my-svg');
Adam Bradley

Grundsätzlich gibt es also keine Möglichkeit, eine Form beim Schweben nach oben (Z-Achse) zu schweben…?
Chharvey

jQuery unterstützt das Ändern der Reihenfolge von SVG-Pfaden nicht.
Senthe

4
@chharvey, Sie können Dinge nach oben schweben lassen, indem Sie sie neu bestellen - neu anhängen. Hier ist ein elegantes Beispiel: codepen.io/osublake/pen/YXoEQe
Frazer Kirkman

36

Eine Alternative zum Verschieben von Elementen im Baum besteht darin, <use>Elemente zu verwenden , bei denen Sie das ändernxlink:href Attribut so , dass Sie die gewünschte z-Reihenfolge erhalten.

Hier ist ein alter Thread auf der Mailingliste von SVG-Entwicklern, in dem dieses Thema im Zusammenhang mit dem Wunsch diskutiert wird, einige Formen zu animieren.

Aktualisieren:

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

In diesem Beispiel ist das <use> -Element das letzte, wodurch es das vorderste Element ist. Wir können jedes der anderen Elemente als vorderstes Element auswählen, indem wir einfach das xlink:hrefAttribut ändern . Im obigen Beispiel haben wir den Kreis mit ausgewählt id="c1", wodurch er als oberstes Element angezeigt wird.

Siehe Geige .


1
Diese Antwort wäre viel nützlicher mit einem Beispiel oder mit den Informationen aus dieser Mailingliste (die gated ist).
Kyeotic

3
Funktioniert, aber Sie müssen die Verwendung entsprechend hinzufügen. Wenn Sie Übersetzungen verwenden, hat <use> keine Ahnung davon
Jochen Bedersdorfer

@JochenBedersdorfer nicht sicher, was du meinst, wie hängen Übersetzungen mit der z-Bestellung zusammen?
Erik Dahlström

War nicht sehr klar darüber. Wenn Sie verschachtelte <g> -Tags mit Transformationen verwenden, müssen Sie die Koordinaten mit getTransformToElement (..) konvertieren. (siehe SVG-Dokumente)
Jochen Bedersdorfer

3
xlink:hrefist veraltet, jetzt ist es nurhref
osvein

22

Das ist eine alte Frage, aber ...

In FireFox (7+) und Chrome (14+) können Sie svg_element nach oben ziehen. Dies gibt Ihnen nicht die Freiheit der vollständigen Steuerung der Z-Achse, aber es ist besser als nichts;)

Fügen Sie dieses Element einfach erneut hinzu.

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

Ich dachte, es würde einen Irrtum auslösen oder so.

appendChild == sich selbst ersetzen == neu zeichnen


3
Überhaupt kein Fehler; appendChildEntfernt zuerst das alte übergeordnete Element, falls vorhanden, auch wenn es mit dem neuen übergeordneten Element identisch ist, und fügt es dann der untergeordneten Liste des neuen übergeordneten Elements hinzu.
Potatoswatter

5

Eine andere nicht erwähnte Lösung besteht darin, jedes SVG-Element / jeden Satz von Elementen in ein Div zu setzen. Sie können den Z-Index der Divs einfach ändern.

Geige: SVG-Elemente wechseln mit Z-Index für Container

... Drücken Sie die Tasten, um das Element nach vorne zu drücken. (vs das ganze Set neu zu streichen und 1 Element nach vorne zu schieben, aber die ursprüngliche Reihenfolge wie in der akzeptierten Lösung beizubehalten)

Es wäre sehr schön, relative Z-Indizes zu haben ...

stackOverflow möchte, dass ich den Code setze, wenn es sich um einen Link von jsfiddle handelt? ... ook




3

SVGverwendet ein "Malermodell" des Renderns. Farbe wird in aufeinanderfolgenden Operationen auf das Ausgabegerät aufgetragen, so dass jede Operation über einen bestimmten Bereich des Ausgabegeräts malt. Wenn der Bereich einen zuvor gestrichenen Bereich überlappt, verdeckt die neue Farbe die alte Verbindung teilweise oder vollständig


3

Um in SVG einen höheren größeren Z-Index zu erhalten, sollten Sie das Element im DOM-Baum nach unten verschieben. Sie können dies mit jQuery tun, indem Sie das SVG-Element auswählen, es entfernen und an der gewünschten Position erneut anhängen:

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

2

Adam Bradleys Kommentar zu Sams Antwort war genau richtig. Es verwendet jQuery anstatt nur CSS, aber er sagte dies:

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

Für das, was ich erstellt habe, musste sich mein SVG-Pfad beim Schweben über jedem anderen Pfad befinden, aber immer noch unter meinem SVG-Text. Also hier ist, was ich mir ausgedacht habe:

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

Sowohl appendTo als auch insertBefore verschieben Ihr Element an eine neue Position, sodass Sie die Tiefe des SVG-Elements nach Belieben ändern können.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.