Допустим, у меня есть пара составных фигур ( <g>
). Я хочу иметь возможность щелкнуть и перетащить их, но я хочу, чтобы тот, который я перетаскиваю в данный момент, находился НАПЕРШЕ другого в Z-порядке, так что если я перетащу его на ДРУГОЙ, другой нужно затмить.
javascript
svg
Кори Трейджер
источник
источник
Ответы:
Индекс Z в SVG определяется порядком появления элементов в документе. Вам нужно будет изменить порядок элементов, если вы хотите вывести определенную форму наверх.
источник
$('#thing-i-want-on-top').appendTo('#my-svg');
Альтернативой перемещению элементов в дереве является использование
<use>
элементов, в которых вы изменяетеxlink:href
атрибут, чтобы он давал вам желаемый z-порядок.Вот старая ветка в списке рассылки svg-developers, обсуждающая эту тему в контексте желания анимировать некоторые формы.
Обновить:
<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"
, что делает его самым верхним элементом.Смотрите скрипку .
источник
xlink:href
устарело, теперь это простоhref
Это старый вопрос, но ...
В 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
сначала удаляет из старого родителя, если таковой имеется, даже если он такой же, как новый родитель, а затем добавляет его в список дочерних элементов нового родителя.Другое решение, о котором не упоминалось, - это поместить каждый элемент / набор элементов svg в div. Вы можете легко изменить z-индекс div.
Fiddle: циклы элементов SVG с z-индексом для контейнеров
... Нажмите на кнопки, чтобы «сдвинуть» этот элемент вперед. (вместо перерисовки всего набора и перемещения 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>
источник
Да, порядок - это то, что определяет, какой объект будет перед другим. Чтобы управлять порядком, вам нужно будет перемещать объекты в DOM. Хороший пример этого есть в вики по SVG по адресу https://www.w3.org/TR/SVG11/render.html#RenderingOrder.
источник
Если вы используете библиотеку svg.js , вы можете использовать команду «.front ()», чтобы переместить любой элемент наверх.
источник
SVG
использует «модель рисования» рендеринга. Paint применяется к устройству вывода в последовательных операциях, так что каждая операция закрашивает некоторую область устройства вывода. Когда область перекрывает ранее окрашенную область, новая краска частично или полностью закрывает старую. - ссылка на этоисточник
В SVG, чтобы получить больший индекс Z, вы должны переместить элемент вниз в дереве DOM. Вы можете сделать это с помощью jQuery, выбрав элемент SVG, удалив его и снова добавив в нужную позицию:
$('g.element').remove().appendTo('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-элемента.
источник