Скажем, у меня есть пара составных фигур (<g>
). Я хочу, чтобы можно было щелкнуть и перетащить их, но я хочу, чтобы тот, с которым я сейчас перетаскиваю, должен быть в верхней части другого в порядке Z, так что, если я перетащил его поверх ДРУГОГО, другой нужно затмить.
С JavaScript я могу изменить индекс Z/слой элемента SVG <g>?
Ответ 1
Z-индекс в SVG определяется порядком появления элементов в документе. Вам нужно будет изменить порядок элементов, если вы хотите перенести определенную фигуру в верхнюю часть.
Ответ 2
Альтернативой перемещающимся элементам в дереве является использование элементов <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.
Ответ 3
Это старый вопрос, но...
В 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
Ответ 4
Да, порядок - это то, что указывает, какой объект будет перед другим. Чтобы управлять порядком, вам нужно будет переместить вещи в DOM. Вот хороший пример этого в SVG wiki: https://www.w3.org/TR/SVG/render.html#RenderingOrder
Ответ 5
Другое решение, о котором не упоминалось, состоит в том, чтобы поместить каждый элемент/набор элементов 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>
Ответ 6
Если вы используете svg.js library, вы можете использовать команду ".front()" для перемещения любого элемента в начало.
Ответ 7
SVG
использует "модель художников" рендеринга. Краска применяется в последовательных операциях к устройству вывода, так что каждая операция рисуется над некоторой областью устройства вывода. Когда область перекрывает ранее окрашенную область, новая краска частично или полностью закрывает старую. ссылка на это
Ответ 8
Комментарий Адама Брэдли к ответу Сэма был точно на месте. Он использует только 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.
Ответ 9
В SVG, чтобы получить более высокий индекс Z, вы должны перемещать элемент вниз в дереве DOM. Вы можете сделать это с помощью jQuery, выбрав элемент SVG, удалив его и добавив его снова в нужное положение:
$('g.element').remove().appendTo('svg');