Digamos que eu tenha algumas formas compostas ( <g>
). Quero poder clicar e arrastá-los, mas quero que aquele que estou arrastando no momento fique em cima do outro na ordem Z, de modo que, se eu arrastá-lo sobre o OUTRO, o outro um deve ser eclipsado.
javascript
svg
Corey Trager
fonte
fonte
Respostas:
O índice Z em SVG é definido pela ordem em que os elementos aparecem no documento. Você terá que alterar a ordem dos elementos se quiser trazer uma forma específica para o topo.
fonte
$('#thing-i-want-on-top').appendTo('#my-svg');
Uma alternativa para mover elementos na árvore é usar
<use>
elementos onde você altera oxlink:href
atributo para que ele forneça a ordem z que você deseja.Aqui está um tópico antigo na lista de discussão svg-developers que discute este tópico no contexto de querer animar algumas formas.
Atualizar:
<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>
Neste exemplo, o elemento <use> é o último, o que o torna o primeiro elemento. Podemos escolher qualquer um dos outros elementos para atuar como frontais simplesmente alterando o
xlink:href
atributo. No exemplo acima, escolhemos o círculo comid="c1"
, o que o faz aparecer como o elemento superior.Veja violino .
fonte
xlink:href
está obsoleto, agora é apenashref
Essa é uma velha questão, mas ...
No FireFox (7 ou superior) e no Chrome (14+), você pode colocar svg_element no topo. Isso não lhe dá liberdade de controle total do eixo z, mas é melhor do que nada;)
Basta anexar esse elemento novamente.
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
Achei que ia gerar um erro ou algo assim.
fonte
appendChild
primeiro remove do pai antigo, se houver, mesmo que seja o mesmo que o novo pai, depois o adiciona à lista de filhos do novo pai.Outra solução não mencionada é colocar cada item svg / conjunto de itens em uma div. Você pode alterar o z-index dos divs facilmente.
Fiddle: ciclos de elementos SVG com z-index para contêineres
... Pressione os botões para 'empurrar' esse elemento para a frente. (vs. repintar todo o conjunto e empurrar 1 elemento para frente, mas mantendo a ordem original como na solução aceita)
Seria muito bom ter índices z relativos ...
stackOverflow quer que eu coloque o código se for um link de jsfiddle? ... ok
Exibir trecho de código
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>
fonte
Sim, a ordem é o que especifica qual objeto estará na frente do outro. Para manipular a ordem, você precisará mover coisas sobre o DOM. Há um bom exemplo disso no wiki SVG em https://www.w3.org/TR/SVG11/render.html#RenderingOrder
fonte
Se você usar a biblioteca svg.js , poderá usar o comando ".front ()" para mover qualquer elemento para o topo.
fonte
SVG
usa um "modelo de pintor" de renderização. A pintura é aplicada em operações sucessivas ao dispositivo de saída, de modo que cada operação pinte sobre alguma área do dispositivo de saída. Quando a área se sobrepõe uma área previamente pintada a nova pintura parcial ou completamente obscurece a old.- link para estefonte
Em SVG, para obter um índice Z maior e mais alto, você deve mover o elemento para baixo na árvore DOM. Você pode fazer isso com jQuery, selecionando o elemento SVG, removendo-o e anexando-o novamente na posição desejada:
$('g.element').remove().appendTo('svg');
fonte
O comentário de Adam Bradley à resposta de Sam foi exatamente direto. Ele usa jQuery em vez de apenas CSS, mas ele disse o seguinte:
$('#thing-i-want-on-top').appendTo('#my-svg');
No entanto, para o que eu estava criando, eu precisava que meu caminho SVG ficasse acima de qualquer outro caminho ao passar o mouse, mas ainda estivesse abaixo do meu texto SVG. Então aqui está o que eu inventei:
$('#thing-i-want-on-top').insertBefore('#id-for-svg-text');
Ambos appendTo e insertBefore moverão seu elemento para um novo local, permitindo que você altere a profundidade do elemento SVG à vontade.
fonte