Ответ 1
Z-индекс в SVG определяется порядком появления элементов в документе. Вам нужно будет изменить порядок элементов, если вы хотите перенести определенную фигуру в верхнюю часть.
Скажем, у меня есть пара составных фигур (<g>
). Я хочу, чтобы можно было щелкнуть и перетащить их, но я хочу, чтобы тот, с которым я сейчас перетаскиваю, должен быть в верхней части другого в порядке Z, так что, если я перетащил его поверх ДРУГОГО, другой нужно затмить.
Z-индекс в SVG определяется порядком появления элементов в документе. Вам нужно будет изменить порядок элементов, если вы хотите перенести определенную фигуру в верхнюю часть.
Альтернативой перемещающимся элементам в дереве является использование элементов <use>
, в которых вы изменяете атрибут xlink:href
, чтобы он дал вам z-упорядочение, которое вы хотите.
Здесь старый поток в почтовом списке svg-developers, обсуждающий этот вопрос в контексте необходимости анимации некоторых фигур.
Update:
<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>
В этом примере элемент <use> является последним, что делает его самым передним элементом. Мы можем выбрать любой из других элементов, чтобы действовать как самый передний, просто изменив атрибут xlink:href
. В приведенном выше примере мы выбрали круг с id="c1"
, что делает его самым верхним элементом.
См. fiddle.
Это старый вопрос, но...
В FireFox (7+) и Chrome (14+) вы можете вывести svg_element в начало. Это не дает вам свободы полного управления осью z, но это лучше, чем ничего;)
Просто добавьте этот элемент еще раз.
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
Я думал, что это собирается выбросить ошибку или что-то в этом роде.
appendChild == replace self == redraw
Да, порядок - это то, что указывает, какой объект будет перед другим. Чтобы управлять порядком, вам нужно будет переместить вещи в DOM. Вот хороший пример этого в SVG wiki: https://www.w3.org/TR/SVG/render.html#RenderingOrder
Другое решение, о котором не упоминалось, состоит в том, чтобы поместить каждый элемент/набор элементов svg в div. Вы можете легко изменить z-индекс div.
Fiddle: Циклы элементов SVG с z-индексом для контейнеров
... Нажмите на кнопки, чтобы "надавить" этот элемент на передний план. (vs перекрашивает весь набор и нажимает 1 элемент на передний план, но сохраняет исходный порядок, как в принятом решении)
Было бы неплохо иметь относительные z-индексы...
stackOverflow хочет, чтобы я поставил код, если это ссылка из 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>
Если вы используете svg.js library, вы можете использовать команду ".front()" для перемещения любого элемента в начало.
SVG
использует "модель художников" рендеринга. Краска применяется в последовательных операциях к устройству вывода, так что каждая операция рисуется над некоторой областью устройства вывода. Когда область перекрывает ранее окрашенную область, новая краска частично или полностью закрывает старую. ссылка на это
Комментарий Адама Брэдли к ответу Сэма был точно на месте. Он использует только jQuery, а не только CSS, но он сказал следующее:
$('#thing-i-want-on-top').appendTo('#my-svg');
Однако для того, что я создавал, мне нужно, чтобы мой SVG-путь был выше любого другого пути при наведении курсора, но все же был ниже моего SVG-текста. Итак, вот что я придумал:
$('#thing-i-want-on-top').insertBefore('#id-for-svg-text');
Оба appendTo и insertBefore перемещают ваш элемент в новое место, позволяя вам по своему усмотрению изменять глубину элемента SVG.
В SVG, чтобы получить более высокий индекс Z, вы должны перемещать элемент вниз в дереве DOM. Вы можете сделать это с помощью jQuery, выбрав элемент SVG, удалив его и добавив его снова в нужное положение:
$('g.element').remove().appendTo('svg');