Pertanyaan Dengan JavaScript, dapatkah saya mengubah indeks / lapisan Z dari elemen SVG?


Katakanlah saya memiliki beberapa bentuk komposit (<g>). Saya ingin dapat mengklik dan menyeretnya, tapi saya ingin yang saya kebetulan menyeret pada saat ini untuk berada di atas yang lain dalam urutan Z, sehingga jika saya menyeretnya ke yang LAIN, yang lain seseorang harus dihilangkan.


75
2018-01-27 02:11


asal


Jawaban:


Indeks Z di SVG didefinisikan oleh urutan elemen-elemen yang muncul dalam dokumen. Anda harus mengubah urutan elemen jika Anda ingin membawa bentuk tertentu ke atas.


102
2018-01-27 02:27



Sebuah alternatif untuk elemen yang bergerak di pohon akan digunakan <use> elemen tempat Anda mengubah xlink:href atribut sehingga memberi Anda z memesan yang Anda inginkan.

Ini sebuah utas lama di milis svg-developers yang membahas topik ini dalam konteks ingin menganimasikan beberapa bentuk.

Memperbarui:

<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>

Dalam contoh ini elemen <use> adalah yang terakhir, yang menjadikannya elemen paling depan. Kita dapat memilih salah satu dari elemen lain untuk bertindak sebagai terdepan hanya dengan mengubah xlink:href atribut. Dalam contoh di atas, kami memilih lingkaran itu id="c1", yang membuatnya tampak sebagai elemen paling atas.

Lihat biola.


25
2018-06-09 08:03



Ini pertanyaan lama, tapi ...

Pada FireFox (7+) dan Chrome (14+) Anda dapat menarik svg_element ke atas. Ini tidak memberi Anda kebebasan kontrol sumbu z penuh, tetapi lebih baik daripada tidak sama sekali;)

Cukup tambahkan elemen itu lagi.

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

Saya pikir itu akan melempar kesalahan atau sesuatu.

appendChild == ganti sendiri == redraw


21
2017-11-07 23:46



Solusi lain yang tidak disebutkan adalah menempatkan setiap item svg / set item ke dalam div. Anda dapat mengubah z-index dari div dengan mudah.

Fiddle: Elemen SVG siklus dengan z-index untuk kontainer

... Tekan tombol untuk 'mendorong' elemen itu ke depan. (vs mengecat ulang seluruh rangkaian dan mendorong 1 elemen ke depan, tetapi menjaga urutan asli seperti pada solusi yang diterima)

Akan sangat menyenangkan memiliki indeks z ...

stackOverflow ingin saya memasukkan kode jika tautan dari 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>


4
2018-03-06 17:49



Jika Anda menggunakan pustaka svg.js, Anda dapat menggunakan perintah ".front ()" untuk memindahkan elemen apa pun ke atas.


4
2018-03-13 12:15



Ya urutannya adalah apa yang menentukan objek apa yang akan berada di depan yang lain. Untuk memanipulasi pesanan, Anda harus memindahkan hal-hal tentang DOM. Ada contoh bagus tentang ini di wiki SVG di https://www.w3.org/TR/SVG/render.html#RenderingOrder


4
2018-01-27 02:49



SVG menggunakan "pelukis model" dari rendering. Cat diterapkan dalam operasi berturut-turut ke perangkat output sedemikian rupa sehingga setiap operasi melukis di beberapa area perangkat output. Ketika area tersebut tumpang tindih dengan area yang dicat sebelumnya cat baru sebagian atau seluruhnya mengaburkan yang lama. tautan ke ini


3
2018-01-16 13:03