251 votes

Comment utiliser le z-index dans les éléments svg ?

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 le z-index dans les g pour montrer les éléments en premier. Dans mon projet, j'ai besoin d'utiliser uniquement la valeur z-index, mais je ne peux pas utiliser le z-index pour mes éléments svg. J'ai beaucoup cherché sur Google mais je n'ai rien trouvé de relatif. Alors s'il vous plaît aidez-moi à utiliser z-index dans mon svg.

Voici le DEMO.

242voto

Maicolpt Points 2298

Spécifications

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

first element -> "painted" first

Référence à la SVG 1.1. Spécification

3.3 Ordre de rendu

Les éléments d'un fragment de document SVG ont un ordre de dessin implicite, avec l'élément premiers éléments dans le fragment de document SVG obtenant "peint" d'abord . Les éléments suivants sont peints par-dessus les éléments précédemment peints.


Solution (plus propre, plus rapide)

Vous devriez mettre le cercle vert comme le dernier objet à être dessiné. Intervertissez donc les deux éléments.

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

Ici la fourchette de votre jsFiddle .

Solution (alternative)

L'étiquette use avec l'attribut xlink:href (juste href para SVG 2 ) et comme valeur l'id de l'élément. Gardez à l'esprit que ce n'est peut-être pas la meilleure solution, même si le résultat semble bon. Ayant un peu de temps, voici le lien de la spécification Élément "utilisation" de SVG 1.1 .

Objectif :

Pour éviter d'obliger les auteurs à modifier le document référencé pour ajouter un ID à l'élément Root.

<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

Spécification SVG 2 est la prochaine version majeure et supporte toujours les fonctionnalités ci-dessus.

3.4. Ordre de rendu

Les éléments en SVG sont positionnés en trois dimensions. En plus de leur position sur les axes x et y de la fenêtre d'affichage SVG, les éléments SVG sont également positionnés sur l'axe z. La position sur l'axe L'axe z définit l'ordre dans lequel ils sont peints. .

Le long de l'axe z, les éléments sont regroupés dans des contextes d'empilement.

3.4.1. Établir un contexte d'empilement en SVG

...

Les contextes d'empilement sont des outils conceptuels utilisés pour décrire l'ordre dans lequel les éléments doivent être peints les uns au-dessus des autres lorsque le document est rendu, ...

48voto

Steve Ladavich Points 2201

Comme d'autres l'ont dit ici, l'indice z 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 du DOM et imiter la fonctionnalité de l'indice Z

Mise à jour de l'index Z d'un élément SVG avec D3

Au niveau le plus élémentaire (et si vous n'utilisez pas les ID pour autre chose), vous pouvez utiliser les ID des éléments comme substitut de l'indice z et les réorganiser. Au-delà, vous pouvez laisser libre cours à votre imagination.

Exemples d'extraits de code

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 la suivante :

  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 d'indices Z utilisés dans les exemples ci-dessous sont les ID, les positions x et y, les rayons, 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.sort pour réorganiser les éléments dans le DOM en fonction des données.

    circles.sort(setOrder);

Exemples

enter image description here

  • Vous pouvez empiler par ID

enter image description here

  • Avec le SVG le plus à gauche en haut

enter image description here

  • Les plus petits rayons en haut

enter image description here

  • Ou spécifier un tableau pour appliquer l'index z pour un ordre spécifique -- dans mon exemple de code le tableau [3,4,1,2,5] déplace/réorganise le 3ème cercle (dans l'ordre HTML original) pour qu'il soit 1er dans le DOM, le 4ème pour qu'il soit 2ème, le 1er pour qu'il soit 3ème, et ainsi de suite...

38voto

Lucas Willems Points 2624

Essayez d'inverser #one y #two . Jetez un coup d'oeil à ce violon : http://jsfiddle.net/hu2pk/3/

Update

En SVG, z-index est défini par l'ordre d'apparition de l'élément dans le document . Vous pouvez également consulter cette page si vous le souhaitez : https://stackoverflow.com/a/482147/1932751

23voto

Jose Rui Santos Points 5381

Vous pouvez utiliser utiliser .

<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

20voto

bumsoverboard Points 422

Comme nous l'avons vu, les svgs sont rendus dans l'ordre et ne tiennent pas compte de l'indice z (pour l'instant). Il faudrait peut-être simplement envoyer l'élément spécifique en 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"));

Ça a marché pour moi.

Mise à jour

Si vous avez un SVG imbriqué, contenant des groupes, vous devrez faire sortir l'élément de son parentNode.

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

Une caractéristique intéressante des SVG est que chaque élément contient son emplacement indépendamment du groupe dans lequel il est imbriqué :+1 :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X