Digamos que tengo un par de formas compuestas ( <g>
). Quiero poder hacer clic y arrastrarlos, pero quiero que el que estoy arrastrando en este momento esté encima del otro en el orden Z, de modo que si lo arrastro sobre el OTRO, el otro uno debería ser eclipsado.
javascript
svg
Corey Trager
fuente
fuente
Respuestas:
El índice Z en SVG se define por el orden en que aparecen los elementos en el documento. Tendrá que cambiar el orden de los elementos si desea llevar una forma específica a la parte superior.
fuente
$('#thing-i-want-on-top').appendTo('#my-svg');
Una alternativa a mover elementos en el árbol es usar
<use>
elementos en los que cambie elxlink:href
atributo para que le proporcione el orden z que desea.Aquí hay un viejo hilo en la lista de correo de svg-developers que discute este tema en el contexto de querer animar algunas formas.
Actualizar:
<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>
En este ejemplo, el elemento <use> es el último, lo que lo convierte en el primer elemento. Podemos elegir cualquiera de los otros elementos para que actúen en primer plano simplemente cambiando el
xlink:href
atributo. En el ejemplo anterior, seleccionamos el círculo conid="c1"
, lo que hace que aparezca como el elemento superior.Ver violín .
fuente
xlink:href
está en desuso, ahora es solohref
Esta es una vieja pregunta, pero ...
En FireFox (7+) y Chrome (14+), puede colocar svg_element en la parte superior. Esto no le da la libertad de control total del eje z, pero es mejor que nada;)
Simplemente agregue ese elemento nuevamente.
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
Pensé que iba a arrojar un error o algo así.
fuente
appendChild
primero elimina del padre anterior, si lo hay, incluso si es el mismo que el nuevo padre, luego lo agrega a la lista de hijos del nuevo padre.Otra solución que no se menciona es poner cada elemento svg / conjunto de elementos en un div. Puede modificar el índice Z de los divs fácilmente.
Fiddle: ciclos de elementos SVG con índice z para contenedores
... Presione los botones para 'empujar' ese elemento hacia el frente. (vs repintar todo el conjunto y empujar 1 elemento al frente, pero manteniendo el orden original como en la solución aceptada)
Sería muy bueno tener índices z relativos ...
stackOverflow quiere que ponga el código si es un enlace de jsfiddle? ... ook
Mostrar fragmento 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>
fuente
Sí, el orden es lo que especifica qué objeto estará frente al otro. Para manipular el orden, deberá mover cosas sobre el DOM. Hay un buen ejemplo de esto en la wiki de SVG en https://www.w3.org/TR/SVG11/render.html#RenderingOrder
fuente
Si usa la biblioteca svg.js , puede usar el comando ".front ()" para mover cualquier elemento a la parte superior.
fuente
SVG
utiliza un "modelo de pintores" de renderizado. La pintura se aplica en operaciones sucesivas al dispositivo de salida de manera que cada operación pinta sobre alguna área del dispositivo de salida. Cuando el área se superpone a un área previamente pintada, la pintura nueva oscurece parcial o completamente la anterior .fuente
En SVG, para obtener un índice Z más grande, debe mover el elemento hacia abajo en el árbol DOM. Puede hacer esto con jQuery, seleccionando el elemento SVG, eliminándolo y agregándolo nuevamente en la posición que desee:
$('g.element').remove().appendTo('svg');
fuente
El comentario de Adam Bradley a la respuesta de Sam fue exactamente acertado. Utiliza jQuery en lugar de solo CSS, pero dijo esto:
$('#thing-i-want-on-top').appendTo('#my-svg');
Sin embargo, para lo que estaba creando, necesitaba que mi ruta SVG estuviera por encima de cualquier otra ruta al pasar el mouse, pero aún debajo de mi texto SVG. Así que esto es lo que se me ocurrió:
$('#thing-i-want-on-top').insertBefore('#id-for-svg-text');
Tanto appendTo como insertBefore moverán su elemento a una nueva ubicación permitiéndole cambiar la profundidad del elemento SVG a voluntad.
fuente