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é.
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.
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.
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
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>
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.
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
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
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é.
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');