Saat ini sedang membangun aplikasi SVG berbasis browser. Dalam aplikasi ini, berbagai bentuk dapat ditata dan diposisikan oleh pengguna, termasuk persegi panjang.
Ketika saya menerapkan elemen stroke-width
SVG rect
katakan 1px
, stroke diterapkan ke rect
offset dan inset dengan cara yang berbeda oleh browser yang berbeda. Ini terbukti merepotkan, terutama ketika saya mencoba menghitung lebar luar dan posisi visual persegi panjang dan menempatkannya di sebelah elemen lain.
Sebagai contoh:
- Firefox menambahkan inset 1px (bawah dan kiri), dan offset 1px (atas dan kanan)
- Chrome menambahkan inset 1px (atas dan kiri), dan offset 1px (bawah dan kanan)
Satu-satunya solusi saya sejauh ini adalah dengan menggambar batas aktual sendiri (mungkin dengan path
alat) dan memposisikan perbatasan di belakang elemen yang dibelai. Tetapi solusi ini merupakan solusi yang tidak menyenangkan, dan saya lebih suka untuk tidak turun jalan ini jika mungkin.
Jadi pertanyaan saya adalah, dapatkah Anda mengontrol bagaimana SVG stroke-width
digambarkan pada elemen?
paint-order
parameter, di mana Anda dapat menentukan, bahwa isian harus diberikan di atas stroke, sehingga Anda akan mendapatkan "penyelarasan luar", lihat jsfiddle.net/hne0kyLg/1Jawaban:
Tidak, Anda tidak bisa menentukan apakah goresannya digambar di dalam atau di luar elemen. Saya membuat proposal ke kelompok kerja SVG untuk fungsi ini pada tahun 2003, tetapi tidak menerima dukungan (atau diskusi).
Seperti yang saya catat dalam proposal,
Sunting : Jawaban ini mungkin salah di masa mendatang. Seharusnya dimungkinkan untuk mencapai hasil ini menggunakan Efek Vektor SVG , dengan menggabungkan
veStrokePath
denganveIntersect
(untuk 'dalam') atau denganveExclude
(untuk 'luar'). Namun, Vector Effects masih merupakan modul konsep kerja tanpa implementasi yang belum dapat saya temukan.Sunting 2 : Spesifikasi konsep SVG 2 mencakup
stroke-alignment
properti (dengan nilai tengah | di dalam | di luar kemungkinan). Properti ini akhirnya bisa menjadi UA.Sunting 3 : Yang mengherankan dan mengecewakan, kelompok kerja SVG telah dihapus
stroke-alignment
dari SVG 2. Anda dapat melihat beberapa masalah yang dijelaskan setelah prosa di sini .sumber
UPDATE: The
stroke-alignment
Atribut pada 1 April 2015 pindah ke spec yang disebut Strokes SVG benar-benar baru .Pada Draft Editor SVG 2.0 tanggal 26 Februari 2015 (dan mungkin sejak 13 Februari) ),
itudengan nilaistroke-alignment
properti hadirinner
,center
(default) danouter
.Tampaknya bekerja dengan cara yang sama dengan
stroke-location
properti yang diusulkan oleh @Phrogz danstroke-position
saran selanjutnya . Properti ini telah direncanakan sejak setidaknya 2011, tetapi terlepas dari anotasi yang mengatakan, tidak pernah dirinci dalam spesifikasi karena ditangguhkan - sampai sekarang, tampaknya.
Tidak ada browser yang mendukung properti ini, atau, sejauh yang saya tahu, salah satu fitur SVG 2 baru, namun mudah-mudahan mereka akan segera setelah spesifikasi matang. Ini adalah properti yang secara pribadi saya ingin miliki, dan saya sangat senang akhirnya ada di spec.
Tampaknya ada beberapa masalah tentang bagaimana properti harus berperilaku di jalur terbuka serta loop. Masalah-masalah ini, kemungkinan besar, akan memperpanjang implementasi lintas browser. Namun, saya akan memperbarui jawaban ini dengan informasi baru ketika browser mulai mendukung properti ini.
sumber
stroke-alignment
dispesifikasikan dalam SVG Strokes, W3C Working Draft. Sementara itu, Draft Editor SVG 2 W3C mengatakan bahwa properti penentuan posisi stroke harus dalam spesifikasi SVG di svgwg.org/svg2-draft/painting.html#SpecifyingStrokePaint , tetapi spec tersebut telah mencapai Status Rekomendasi Calon W3C dan tidak ada properti seperti itu. di spec selain dari tautan kestroke-position
proposal, membuatnya tampak seperti itu tidak akan terjadi.Saya menemukan cara mudah, yang memiliki beberapa batasan, tetapi berhasil bagi saya:
Berikut ini contoh kerjanya:
sumber
<use>
? Mengapa tidak langsung menempatkan path dan clip path? Ini bekerja dengan baik:<svg width="240" height="240" viewBox="0 0 1024 1024"> <path id="ld" d="M256,0 L0,512 L384,512 L128,1024 L1024,384 L640,384 L896,0 L256,0 Z" clip-path="url(#clip)" stroke="#0081C6" stroke-width="160" fill="#00d2b8"/> <clipPath id="clip"> <use xlink:href="#ld"/> </clipPath> </svg>
. (Ya, ini sepenuhnya masuk akal dan benar SVG dan akan membuat dengan benar di mana-mana. Jangan takut rekursi.)Anda dapat menggunakan CSS untuk memberi gaya urutan goresan dan isi. Artinya, stroke dulu lalu isi kedua, dan dapatkan efek yang diinginkan.
MDN di
paint-order
: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/paint-orderKode CSS:
sumber
Berikut adalah fungsi yang akan menghitung berapa banyak piksel yang perlu Anda tambahkan - menggunakan goresan yang diberikan - ke atas, kanan, bawah dan kiri, semuanya berdasarkan browser:
sumber
Seperti yang dicatat oleh orang-orang di atas, Anda harus menghitung ulang offset ke koordinat path stroke atau menggandakan lebar dan kemudian menutupi satu sisi atau yang lain, karena SVG tidak hanya secara alami mendukung penyelarasan stroke Illustrator, tetapi PostScript tidak juga .
Spesifikasi untuk stroke dalam Manual Adobe PostScript negara edisi ke-2: " 4.5.1 Sambil membelai: The Stroke Operator menarik garis dari beberapa ketebalan sepanjang jalan saat Untuk setiap segmen lurus atau melengkung di jalan,. Stroke menarik garis yang berpusat pada segmen dengan sisi yang sejajar dengan segmen. " (Penekanan mereka)
Spesifikasi lainnya tidak memiliki atribut untuk mengimbangi posisi garis. Ketika Illustrator memungkinkan Anda menyelaraskan di dalam atau di luar, itu menghitung ulang offset jalur yang sebenarnya (karena itu masih lebih murah secara komputasi daripada mencetak lebih dari lalu menutupi). Koordinat jalur dalam dokumen .ai adalah referensi, bukan apa yang di-raster atau diekspor ke format final.
Karena format asli Inkscape adalah spec SVG, ia tidak dapat menawarkan fitur yang tidak dimiliki spec.
sumber
Berikut ini adalah pekerjaan untuk menggunakan batas dalam dan .
rect
symbol
use
Contoh : https://jsbin.com/yopemiwame/edit?html,output
SVG :
Catatan: Pastikan untuk mengganti
?
inuse
dengan nilai real.Latar Belakang : Alasan mengapa ini bekerja adalah karena simbol menetapkan viewport baru dengan mengganti
symbol
dengansvg
dan menciptakan unsur dalam DOM bayangan. Inisvg
dari bayangan DOM kemudian dihubungkan keSVG
elemen Anda saat ini . Perhatikan bahwasvg
s dapat disarangkan dan setiapsvg
membuat viewport baru, yang memotong semua yang tumpang tindih, termasuk perbatasan yang tumpang tindih. Untuk ikhtisar yang lebih terperinci tentang apa yang terjadi, baca artikel fantastis ini oleh Sara Soueidan.sumber
Saya tidak tahu bagaimana itu akan membantu tetapi dalam kasus saya, saya hanya membuat lingkaran lain dengan perbatasan saja dan meletakkannya "di dalam" bentuk lainnya.
sumber
Solusi (kotor) yang mungkin adalah dengan menggunakan pola,
di sini adalah contoh dengan segitiga di dalam:
https://jsfiddle.net/qr3p7php/5/
sumber
Solusi dari Xavier Ho untuk menggandakan lebar goresan dan mengubah urutan cat adalah brilian, meskipun hanya berfungsi jika isiannya berwarna solid, tanpa transparansi.
Saya telah mengembangkan pendekatan lain, lebih rumit tetapi bekerja untuk mengisi apa pun. Ini juga bekerja di elips atau jalur (dengan yang kemudian ada beberapa kasus sudut dengan perilaku aneh, misalnya jalur terbuka yang melintasi diri mereka sendiri, tetapi tidak banyak).
Caranya adalah dengan menampilkan bentuk dalam dua lapisan. Satu tanpa goresan (hanya isian), dan satunya lagi dengan goresan dengan lebar ganda (isian transparan) dan melewati topeng yang menunjukkan seluruh bentuk, tetapi menyembunyikan bentuk asli tanpa goresan.
sumber