Avec JavaScript, puis-je changer l'index Z / layer D'un élément SVG?

Disons que j'ai quelques formes composites (<g>). Je veux être en mesure de cliquer et faire glisser, mais je veux celui que j'arrive à glisser, à l'instant d'être sur le DESSUS de l'autre dans l'ordre, de sorte que si je la faire glisser par-dessus l'AUTRE, l'autre devrait être éclipsé.

76
demandé sur Volker E. 2009-01-27 05:11:12

9 réponses

L'index Z en SVG est défini par l'ordre dans lequel les éléments apparaissent dans le document. Vous devrez changer l'ordre des éléments si vous voulez apporter une forme spécifique au sommet.

102
répondu Sam 2009-01-27 02:27:58

Une alternative au déplacement d'éléments dans l'arborescence consiste à utiliser des éléments <use> où vous modifiez l'attribut xlink:href afin qu'il vous donne l'ordre z souhaité.

Voici un vieux fil sur svg-developers mailinglist discutant de ce sujet dans le contexte de vouloir animer certaines formes.

Mise à Jour:

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

Dans cet exemple, l'élément est le dernier, ce qui en fait l'élément le plus en avant. Nous pouvons choisir l'un des autres éléments pour agir comme frontmost simplement en changeant l'attribut xlink:href. Dans l'exemple ci-dessus, nous avons choisi le cercle de id="c1", ce qui le fait apparaître comme l'élément supérieur.

Voir violon.

26
répondu Erik Dahlström 2014-03-25 13:43:26

C'est une vieille question, mais...

Sur FireFox (7+) et Chrome (14+), Vous pouvez tirer svg_element vers le haut. Cela ne vous donne pas la liberté de contrôle complet de l'axe z, mais c'est mieux que rien;)

Ajoutez simplement cet élément à nouveau.

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

Je pensais qu'il allait jeter en erreur ou quelque chose.

AppendChild = = se remplacer = = redessiner

21
répondu CoR 2011-11-07 23:46:50

Une autre solution non mentionnée est de placer chaque élément svg/ensemble d'éléments dans un div. Vous pouvez modifier l'index z des divs facilement.

Fiddle: éléments SVG cycles avec Z-index pour les conteneurs

...Appuyez sur les boutons pour "pousser" cet élément vers l'avant. (vs repeindre l'ensemble et pousser 1 élément à l'avant, mais en gardant l'ordre d'origine comme dans la solution acceptée)

Ce serait très bien d'avoir des indices z relatifs...

StackOverflow veut moi pour mettre le code si c'est un lien de jsfiddle?...ook

var orderArray=[0,1,2];
var divArray = document.querySelectorAll('.shape');
var buttonArray = document.querySelectorAll('.button');

for(var i=0;i<buttonArray.length;i++){
    buttonArray[i].onclick=function(){
        var localI = i;
        return function(){clickHandler(orderArray.indexOf(localI));};
    }();
}


function clickHandler(divIndex) {
     orderArray.push(orderArray.splice(divIndex, 1)[0]);
    orderDivs();
}

function orderDivs(){
    for(var i=0;i<orderArray.length;i++){
       divArray[orderArray[i]].style.zIndex=i;        
    }
}
svg {
    width: 100%;
    height: 100%;
    stroke: black;
    stroke-width:2px;
    pointer-events: all;
}
div{
    position:absolute;
}
div.button{
    top:55%;
    height:5%;
    width:15%;
    border-style: outset;
    cursor:pointer;
    text-align: center;
    background:rgb(175, 175, 234);
    
}
div.button:hover{
    border-style: inset;
    background:yellow;
    
}
div.button.first{
    left:0%;
}
div.button.second{
    left:20%;
}
div.button.third{
    left:40%;
}
<div class="shape">
    <svg>
    <circle cx="50" cy="50" r="40" fill="lime" />
    </svg>
</div>
<div class="shape">
    <svg>
        <rect x="4" y="20" width="200" height="50" fill="cyan" />
    </svg>
</div>
<div class="shape">
    <svg>
        <circle cx="70" cy="70" r="50" fill="fuchsia" />
    </svg>
</div>

<div class='button first'>lime</div>
<div class='button second'>cyan</div>
<div class='button third'>fuchsia</div>
4
répondu Roman Rekhler 2015-03-06 17:49:15

Si vous utilisez le svg.bibliothèque js, vous pouvez utiliser le bouton ".front()" commande pour déplacer n'importe quel élément vers le haut.

4
répondu Erel Segal-Halevi 2015-03-13 12:15:44

Oui l'ordre est ce qui spécifie quel objet sera devant l'autre. Pour manipuler l'ordre, vous devrez déplacer des choses sur le DOM. Il y a un bon exemple de ceci sur le wiki SVG à https://www.w3.org/TR/SVG/render.html#RenderingOrder

4
répondu Kelly Anderson 2016-06-10 14:04:33

SVG utilise un" modèle de peintres " de rendu. La peinture est appliquée dans des opérations successives au dispositif de sortie de telle sorte que chaque opération peint sur une certaine zone du dispositif de sortie. Lorsque la zone chevauche une zone précédemment peinte, la nouvelle peinture obscurcit partiellement ou complètement l'ancienne.- lien vers ce

3
répondu Ishank Dubey 2014-01-16 13:03:03

Le commentaire D'Adam Bradley à la réponse de Sam était exactement sur le point. Il utilise jQuery plutôt que CSS seulement, mais il a dit ceci:

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

Cependant, pour ce que je créais, j'avais besoin que mon chemin SVG soit au-dessus de tout autre chemin sur hover, mais toujours en dessous de mon texte SVG. Alors voici ce que je suis venu avec:

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

AppendTo et insertBefore déplaceront votre élément vers un nouvel emplacement vous permettant de changer la profondeur de L'élément SVG à volonté.

0
répondu FiSH GRAPHICS 2016-08-26 11:54:48

En SVG, pour obtenir un index Z plus grand, vous devez déplacer l'élément vers le bas dans L'arborescence DOM. Vous pouvez le faire avec jQuery, en sélectionnant L'élément SVG, en le supprimant et en l'ajoutant à nouveau à la position souhaitée:

$('g.element').remove().appendTo('svg');
0
répondu Agu Dondo 2016-10-04 21:00:36