Comment utiliser z-index dans svg elements?

j'utilise les cercles svg dans mon projet comme ceci,

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

et j'utilise l'index-z de la balise g pour montrer les éléments du premier. Dans mon projet, Je ne dois utiliser que l'indice z, mais je ne peux pas utiliser l'indice z pour mes éléments svg. J'ai beaucoup cherché sur Google mais je n'ai rien trouvé relativement. Alors aidez-moi à utiliser z-index dans mon svg.

Voici la démo .

95
demandé sur Donald Duck 2013-07-22 15:38:29

11 réponses

Spécification

Dans la spécification SVG version 1.1 de l'ordre de rendu basé sur le document de l'ordre:

first element -> "painted" first

référence à la spécification: SVG 1.1 Rendering Order

3.3 Ordonnance D'Équarrissage

les éléments d'un fragment de document SVG ont un ordre de dessin implicite, avec les premiers éléments du fragment de document SVG obtenant "peint" en premier. Les éléments suivants sont peints sur des éléments déjà peints.


Solution (nettoyant plus rapide)

vous devez mettre le cercle vert comme dernier objet à dessiner.

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

Voici la fourche de votre jsFiddle .

Solution (alternative)

l'étiquette use avec l'attribut xlink:href et comme valeur l'id de l'élément. Gardez à l'esprit que pourrait ne pas être la meilleure solution, même si le résultat semble bien. Ayant un peu de temps, voici le lien de la spécification SVG 1.1 "utiliser" élément .

But:

pour éviter d'exiger des auteurs qu'ils modifient le document référencé pour ajouter un ID à l'élément racine.

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

Notes sur SVG 2

SVG 2 est la prochaine version de la norme https://www.w3.org/TR/SVG2 / .

3.4 Ordonnance D'Équarrissage

Les éléments

en SVG sont positionnés en trois dimensions. En plus de leur position sur les axes x et y de SVG viewport, les éléments SVG sont également positionnés sur l'axe des z. La position sur l'axe z définit l'ordre dans lequel ils sont peints.

...

3.4.1. Ordre de rendu de l'élément de contrôle: la propriété 'index-z '

...

112
répondu Maicolpt 2018-03-16 00:05:45

Essayez d'inverser #one et #two . Regardez ce violon: http://jsfiddle.net/hu2pk/3 /

Update

En SVG, z-index est défini par l'ordre de l'élément apparaît dans le document . Vous pouvez aussi regarder cette page si vous voulez : https://stackoverflow.com/a/482147/1932751

25
répondu Lucas Willems 2017-05-23 12:10:54

vous pouvez utiliser utilisez .

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

le cercle vert apparaît en haut.

jsFiddle

18
répondu Jose Rui Santos 2014-10-09 11:36:36

comme d'autres l'ont dit ici, z-index est défini par l'ordre dans lequel l'élément apparaît dans le DOM. Si réordonner manuellement votre html n'est pas une option ou serait difficile, vous pouvez utiliser D3 pour réordonner les groupes/objets SVG.

utiliser D3 pour mettre à jour L'ordre DOM et imiter la fonctionnalité de L'Index en Z

mise à Jour d'un Élément SVG Z-Index Avec D3

Au niveau le plus élémentaire (et si vous vous pouvez utiliser l'IDs d'élément comme un stand-in pour z-index et réordonner avec ceux-ci. Au-delà, vous pouvez laisser libre cours à votre imagination.

exemples dans le code snippet

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>

l'idée de base est:

  1. utilisez D3 pour sélectionner les éléments SVG DOM.

    var circles = d3.selectAll('circle')
    
  2. créez un tableau d'indices z avec une relation 1:1 avec vos éléments SVG (que vous voulez réorganiser). Les tableaux z-index utilisés dans les exemples ci-dessous sont IDs, X & Y position, radii, etc....

    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. ensuite, utilisez D3 pour lier vos indices z à cette sélection.

    circles.data(zOrders[setOrderBy]);
    
  4. enfin, appelez D3.Trier pour réordonner les éléments dans le DOM basé sur les données.

    circles.sort(setOrder);
    

exemples

enter image description here

  • vous pouvez empiler par ID

enter image description here

  • Avec la de gauche SVG sur le dessus

enter image description here

  • plus petits rayons sur le dessus

enter image description here

  • Ou Spécifier un tableau pour appliquer z-index pour un classement spécifique -- dans mon code d'exemple le tableau [3,4,1,2,5] bouge/trie le 3e cercle (dans le HTML d'origine) afin de être 1er dans le DOM, 4ème être 2ème, 1er être 3ème, et ainsi de suite...

18
répondu Steve Ladavich 2017-05-23 11:47:36

il n'y a pas d'indice z pour les SVG. Mais svg détermine lequel de vos éléments est le plus haut par sa position dans le DOM. Ainsi, vous pouvez supprimer l'Objet et le placer à la fin du svg en faisant le "dernier rendu" de l'élément. Celui-ci est alors rendu "topmost" visuellement.


en utilisant jQuery:

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

utilisation:

moveUp($('#myTopElement'));

Utilisant D3.js:

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

utilisation:

myTopElement.moveUp();

7
répondu Hafenkranich 2016-10-24 22:22:45

Utilisant D3:

si vous voulez ajouter l'élément dans l'ordre inverse aux données Utiliser:

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

au lieu de .annexe 151920920"

Ajout d'un élément au sommet d'un élément de groupe

5
répondu Nathan Hensher 2017-05-23 12:18:36

tel que discuté, les SVG rendent dans l'ordre et ne prennent pas en compte l'index-z (pour le moment). Peut-être qu'il suffit d'envoyer l'élément spécifique au bas de son parent pour qu'il soit rendu en dernier.

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

travaillait pour moi.

5
répondu bumsoverboard 2017-11-15 03:55:14

Utilisant D3:

si vous voulez réinsérer chaque élément sélectionné, dans l'ordre, comme dernier enfant de son parent.

selection.raise()
5
répondu Diso 2018-07-30 03:53:11

une autre solution serait d'utiliser des divs, qui utilisent ZIndex pour contenir les éléments SVG.Comme ici: https://stackoverflow.com/a/28904640/4552494

3
répondu Roman Rekhler 2015-03-06 18:15:41

Push élément SVG pour durer, de sorte que son z-index seront au top. En SVG, il n'y a pas de propriété appelée z-index. essayez javascript ci-dessous pour mettre l'élément en haut.

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

cible: est un élément pour lequel nous devons l'amener en haut svg: est le conteneur d'éléments

1
répondu Vaseem AbdulSamad 2018-07-29 09:12:52

les solutions propres, rapides et faciles affichées à la date de cette réponse sont insatisfaisantes. Ils sont construits sur la déclaration erronée que les documents SVG ne sont pas d'ordre z. Les bibliothèques ne sont pas nécessaires. Une ligne de code peut effectuer la plupart des opérations pour manipuler l'ordre z des objets ou des groupes d'objets qui pourraient être nécessaires dans le développement d'une application qui déplace des objets 2D autour dans un espace x-y-Z.

Z Fragments de document SVG

ce qu'on appelle un fragment de document SVG est un arbre d'éléments dérivé du type de noeud de base SVGElement. Le noeud racine d'un fragment de document SVG est un SVGSVGElement, qui correspond à une balise HTML5 . Le SVGGElement correspond à l'étiquette et permet de regrouper des enfants.

avoir un attribut index-z Sur le SVGElement comme dans CSS serait une défaite le modèle de rendu SVG. Sections 3.3 et 3.4 de la recommandation V1 du W3C SVG.1 la 2ème édition stipule que les fragments de document SVG (arbres de descendance D'un SVGSVGElement) sont rendus en utilisant ce qui est appelé un première recherche de profondeur de l'arbre . Ce schéma est un ordre de z dans tous les sens du terme.

Z Ordre est en fait un raccourci de vision d'ordinateur pour éviter le besoin d'un véritable rendu 3D avec les complexités et les exigences de calcul du traçage des rayons. Le équation linéaire pour l'indice z implicite des éléments d'un fragment de document SVG.

z-index = z-index_of_svg_tag + depth_first_tree_index / tree_node_qty

c'est important parce que si vous voulez déplacer un cercle qui était au-dessous d'un carré au-dessus de lui, vous insérez simplement le carré avant le cercle. Cela peut être fait facilement en JavaScript.

Soutenir Les Méthodes

Les instances

SVGElement ont deux méthodes qui supportent la manipulation simple et facile de l'ordre z.

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

La Réponse Correcte Qui Ne crée pas de Désordre

parce que le SVGGElement ( tag) peut être enlevé et inséré aussi facilement qu'un SVGCircleElement ou toute autre forme, les couches d'image typiques des produits Adobe et d'autres outils graphiques peuvent être implémenté avec facilité en utilisant le SVGGElement. Ce JavaScript est essentiellement un déplacer en dessous de commande.

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

si la couche d'un robot dessiné comme les enfants de SVGGElement gRobot était avant la porte dessinée comme les enfants de SVGGElement gDoorway, le robot est maintenant derrière la porte parce que l'ordre z de la porte est maintenant un plus l'ordre z du robot.

Un passer au-Dessus de "151980920 de la commande" est presque aussi facile.

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

pense a=A et b = b Pour te souvenir de ça.

insert after = move above
insert before = move below

quitter le DOM dans un État compatible avec la vue

la raison pour laquelle cette réponse est correcte est qu'elle est minime et complète et, comme les internes D'Adobe products ou d'autres éditeurs graphiques bien conçus, laisse la représentation interne dans un État qui est compatible avec la vue créée par le rendu.

Alternative Mais Limitée Approche

une autre approche couramment utilisée consiste à utiliser le CSS z-index en conjonction avec plusieurs fragments de documents SVG (étiquettes SVG) avec des fonds pour la plupart transparents dans tous sauf le bas. Encore une fois, cela va à l'encontre de l'élégance du modèle de rendu SVG, ce qui rend difficile le déplacement des objets vers le haut ou vers le bas dans l'ordre z.


NOTES::

  1. ( https://www.w3.org/TR/SVG/render.html v 1.1, 2e édition, 16 août 2011)

    3.3 ordre de rendu les éléments d'un fragment de document SVG ont un ordre de dessin implicite, avec les premiers éléments du document SVG fragment se faisant "peindre" en premier. Les éléments suivants sont peints sur haut d'éléments déjà peints.

    3.4 comment les groupes sont rendus Le groupement d'éléments tels que l'élément " g " (voir éléments de conteneur) a pour effet de produire un toile séparée initialisée en noir transparent sur laquelle l'enfant les éléments sont peints. Après l'achèvement du groupe, tout filtre les effets spécifiés pour le groupe sont appliqués pour créer un temporaire de la toile. La toile temporaire modifiée est composée dans le contexte, en tenant compte de tout masquage et opacité au niveau du groupe paramètres sur le groupe.

0
répondu Douglas Daseeco 2018-06-18 20:26:14