Bagaimana saya bisa membuat skala svg dengan wadah induknya?

236

Saya ingin memiliki skala isi elemen svg sebaris saat ukurannya bukan asli. Tentu saja saya bisa memilikinya sebagai file terpisah dan skala seperti itu.

index.html: <img src="foo.svg" style="width: 100%;" />

foo.svg: <svg width="123" height="456"></svg>

Namun, saya ingin menambahkan gaya tambahan ke SVG melalui CSS, jadi menautkan yang eksternal bukanlah suatu pilihan. Bagaimana cara membuat skala SVG sebaris?

bjb568
sumber
2
coba presents dalam lebar dan tinggi svg.
ncm
@ ncm Bagaimana hal itu dilakukan dengan JS?
Mawg mengatakan mengembalikan Monica

Jawaban:

458

Untuk menentukan koordinat dalam gambar SVG secara independen dari ukuran skala gambar, gunakan viewBoxatribut pada elemen SVG untuk menentukan apa kotak pembatas gambar dalam sistem koordinat gambar, dan menggunakan atribut widthdan heightuntuk menentukan apa lebar atau tinggi sehubungan dengan halaman yang berisi.

Misalnya, jika Anda memiliki yang berikut:

<svg>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

Ini akan dirender sebagai segitiga 10px kali 20px:

10x20 segitiga

Sekarang, jika Anda hanya mengatur lebar dan tinggi, itu akan mengubah ukuran elemen SVG, tetapi tidak skala segitiga:

<svg width=100 height=50>
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

10x20 segitiga

Jika Anda mengatur kotak tampilan, yang menyebabkannya mengubah gambar sedemikian rupa sehingga kotak yang diberikan (dalam sistem koordinat gambar) diskalakan agar sesuai dengan lebar dan tinggi yang diberikan (dalam sistem koordinat halaman). Misalnya, untuk meningkatkan segitiga menjadi 100px kali 50px:

<svg width=100 height=50 viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 segitiga

Jika Anda ingin meningkatkannya ke lebar viewport HTML:

<svg width="100%" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x150 segitiga

Perhatikan bahwa secara default, rasio aspek dipertahankan. Jadi, jika Anda menentukan bahwa elemen tersebut harus memiliki lebar 100%, tetapi ketinggian 50px, itu sebenarnya hanya akan skala hingga ketinggian 50px (kecuali Anda memiliki jendela yang sangat sempit):

<svg width="100%" height="50px" viewBox="0 0 20 10">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

100x50 segitiga

Jika Anda benar-benar ingin peregangan horizontal, nonaktifkan pelestarian rasio aspek dengan preserveAspectRatio=none:

<svg width="100%" height="50px" viewBox="0 0 20 10" preserveAspectRatio="none">
    <polygon fill=red stroke-width=0 
             points="0,10 20,10 10,0" />
</svg>

300x50 segitiga

(perhatikan bahwa dalam contoh saya, saya menggunakan sintaks yang berfungsi untuk penyematan HTML, untuk memasukkan contoh sebagai gambar di StackOverflow. Saya malah menyematkan dalam SVG lain, jadi saya perlu menggunakan sintaks XML yang valid)

Brian Campbell
sumber
1
Bagaimana Anda membuat tidak hanya viewBox preserveAspectRatio, tetapi juga kotak utama? Saya ingin lebar: 100%; tinggi: otomatis untuk itu.
bjb568
1
@ Bung: Saya pikir contoh dengan width="100%"dan tanpa tinggi yang ditentukan melakukan apa yang Anda inginkan. Saya telah menambahkan gambar untuk diperagakan. Ini memiliki lebar 100%, dan meningkatkan tinggi secara proporsional. Jika bukan itu yang Anda cari, dapatkah Anda mencoba menjelaskan apa yang Anda maksud?
Brian Campbell
1
Oh Sebenarnya tidak masalah. Itu hanya bug webkit. Di Safari dan Chrome, ketinggian "asli" adalah 100% secara default, bukan otomatis. Bagaimana saya bisa mengatasi ini?
bjb568
4
@ Bung Ah, ya, saya mengerti. Ini berfungsi baik di Firefox, tetapi tidak ada Chrome atau Safari. Menurut Spesifikasi SVG , Firefox tampaknya benar; sementara nilai default dari widthdan heightuntuk elemen SVG adalah 100%, ini bukan definisi CSS dari 100% (100% dari blok yang mengandung), tetapi 100% dari viewport yang telah ditentukan berdasarkan rasio aspek intrinsik ( yang dihitung dari viewBoxsaat itu diberikan). Saya belum menemukan solusi untuk masalah itu yang berfungsi di Chrome / Safari.
Brian Campbell
1
Ini bekerja untuk saya. Saya pertama kali membuat atribut viewBox pada elemen SVG dan mengatur nilainya menjadi "0 0 [lebar svg asli] [ketinggian svg asli]". Selanjutnya saya mengubah atribut lebar elemen SVG menjadi "otomatis" dan atribut tinggi menjadi "100%". Wadah juga harus memiliki ketinggian yang ditentukan. Ini menskala vektor hingga 100% dari tinggi wadah, memungkinkan lebar melayang. Terakhir, atur CSS max-width SVG menjadi 100% untuk mencegah overshooting wadah.
Ryan Griggs
28

Setelah 48 jam penelitian, saya akhirnya melakukan ini untuk mendapatkan penskalaan proporsional:

CATATAN: Sampel ini ditulis dengan React. Jika Anda tidak menggunakannya, ubah kembali kasing unta ke tanda hubung (yaitu: ubah backgroundColorke background-colordan ubah Objectkembali ke a String).

<div
  style={{
    backgroundColor: 'lightpink',
    resize: 'horizontal',
    overflow: 'hidden',
    width: '1000px',
    height: 'auto',
  }}
>
  <svg
    width="100%"
    viewBox="113 128 972 600"
    preserveAspectRatio="xMidYMid meet"
  >
    <g> ... </g>
  </svg>
</div>

Inilah yang terjadi dalam kode contoh di atas:

VIEWBOX

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

min-x, min-y, lebar dan tinggi

yaitu: viewbox = "0 0 1000 1000"

Viewbox adalah atribut penting karena pada dasarnya memberitahu SVG apa ukuran untuk menggambar dan di mana. Jika Anda menggunakan CSS untuk membuat SVG 1000x1000 px tetapi kotak pandang Anda adalah 2000x2000, Anda akan melihat bagian kiri atas SVG Anda.

Dua angka pertama, min-x dan min-y, menentukan apakah SVG harus diimbangi di dalam viewbox.

SVG saya perlu bergeser ke atas / bawah atau kiri / kanan

Periksa ini: viewbox = "50 50 450 450"

Dua angka pertama akan menggeser SVG Anda ke kiri 50px dan naik 50px, dan dua angka kedua adalah ukuran kotak tampilan: 450x450 px. Jika SVG Anda berukuran 500x500 tetapi memiliki lapisan tambahan di atasnya, Anda dapat memanipulasi angka-angka itu untuk memindahkannya di dalam "kotak centang".

Tujuan Anda pada titik ini adalah mengubah salah satu dari angka-angka itu dan melihat apa yang terjadi.

Anda juga dapat sepenuhnya menghilangkan kotak view, tetapi milage Anda akan bervariasi tergantung pada setiap pengaturan lain yang Anda miliki saat itu. Dalam pengalaman saya, Anda akan menemukan masalah dengan mempertahankan rasio aspek karena kotak view membantu menentukan rasio aspek.

PRESERVE RASIO ASPEK

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/preserveAspectRatio

Berdasarkan penelitian saya, ada banyak pengaturan rasio aspek yang berbeda, tetapi yang standar disebut xMidYMid meet. Saya menaruhnya di atas milik saya untuk secara eksplisit mengingatkan diri sendiri. xMidYMid meetmenjadikannya skala secara proporsional berdasarkan titik tengah X dan Y. Ini berarti ia tetap terpusat di viewbox.

LEBAR

MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/width

Lihatlah contoh kode saya di atas. Perhatikan bagaimana saya mengatur lebar saja, tidak tinggi. Saya mengaturnya menjadi 100% sehingga mengisi wadah tempatnya. Inilah yang mungkin berkontribusi paling banyak untuk menjawab pertanyaan Stack Overflow ini.

Anda dapat mengubahnya ke nilai piksel apa pun yang Anda inginkan, tetapi saya sarankan menggunakan 100% seperti yang saya lakukan untuk meledakkannya hingga ukuran maksimal dan kemudian mengontrolnya dengan CSS melalui wadah induk. Saya merekomendasikan ini karena Anda akan mendapatkan kontrol "tepat". Anda dapat menggunakan kueri media dan Anda dapat mengontrol ukuran tanpa JavaScript gila.

SKALA DENGAN CSS

Lihatlah contoh kode saya di atas lagi. Perhatikan bagaimana saya memiliki properti ini:

resize: 'horizontal', // you can safely omit this
overflow: 'hidden',   // if you use resize, use this to fix weird scrollbar appearance
width: '1000px',
height: 'auto',

Ini tambahan, tetapi ini menunjukkan kepada Anda bagaimana memungkinkan pengguna untuk mengubah ukuran SVG sambil mempertahankan rasio aspek yang tepat. Karena SVG mempertahankan rasio aspeknya sendiri, Anda hanya perlu membuat lebar dapat diubah ukurannya pada wadah induk, dan itu akan mengubah ukuran sesuai keinginan.

Kami membiarkan tinggi sendirian dan / atau mengaturnya menjadi otomatis, dan kami mengontrol ukurannya dengan lebar. Saya memilih lebar karena seringkali lebih bermakna karena desain yang responsif.

Berikut adalah gambar dari pengaturan ini yang digunakan:

masukkan deskripsi gambar di sini

Jika Anda membaca setiap solusi dalam pertanyaan ini dan masih bingung atau tidak mengerti apa yang Anda butuhkan, lihat tautan ini di sini. Saya merasa sangat membantu:

https://css-tricks.com/scale-svg/

Ini adalah artikel yang sangat besar, tapi itu memecah hampir setiap cara yang mungkin untuk memanipulasi SVG, dengan atau tanpa CSS. Saya sarankan membacanya sambil santai minum kopi atau cairan pilihan Anda.

agm1984
sumber
Ini sepertinya tidak berfungsi untuk SVG mana pun - Jika Anda tidak memiliki kendali atas sumber SVG, maka metode ini gagal ketika SVG memiliki lebar tetap.
user48956
@ user48956 Anda selalu dapat memanipulasinya setelah menggunakan JavaScript.
Andrew
Ya - Anda selalu dapat menyodok bagian dalam berbagai format file dengan pemrograman - tetapi Anda berharap akan ada metode yang bekerja untuk semua jenis aset (misalnya PNG) dan tidak memerlukan pemrograman JavaScript.
user48956
21

Anda ingin melakukan transformasi seperti itu:

dengan JavaScript:

document.getElementById(yourtarget).setAttribute("transform", "scale(2.0)");

Dengan CSS:

#yourtarget {
  transform:scale(2.0);
  -webkit-transform:scale(2.0);
}

Bungkus Halaman SVG Anda dengan tag Grup dan targetkan untuk memanipulasi seluruh halaman:

<svg>
  <g id="yourtarget">
    your svg page
  </g>
</svg>

Catatan : Skala 1.0 adalah 100%

Gary Hayes
sumber
7
Baik. Saya tidak ingin JS dalam hal ini. Apakah ada cara untuk mengubahnya agar sesuai dengan orang tua?
bjb568
@ bj setAttribute adalah hal yang sama dengan <tag attribute = "value">
john ktejik
17

Mengacaukan & menemukan CSS ini tampaknya mengandung SVG di browser Chrome sampai pada titik di mana wadah lebih besar dari gambar:

div.inserted-svg-logo svg { max-width:100%; }

Tampaknya juga bisa berfungsi di FF + IE 11.

Kerry7777
sumber
Ini memecahkan masalah bagi saya. Saya hanya melihat overflow di iOS. Terima kasih!
Evan Mattson
5
Menggunakan keduanya max-width: 100%dan max-height: 100%akan membuat svg selalu skala ke wadah tanpa pernah meluap atau kehilangan aspek rasio.
Gavin
2
@ Gavin max-height: 100%tidak bekerja untuk saya, diselesaikan dengan menggunakan vhbukannya%
Pavel
2

mengubah file SVG bukan solusi yang adil bagi saya jadi saya menggunakan unit CSS relatif .

vh, vw, %Yang sangat berguna. Saya menggunakan CSS ingin height: 2.4vh;mengatur ukuran dinamis ke gambar SVG saya.

canbax
sumber
1

Cara sederhana lainnya adalah

transform: scale(1.5);
Kasim ŞEN
sumber
0

Menyesuaikan atribut currentScale berfungsi di IE (saya diuji dengan IE 11), tetapi tidak di Chrome.

Fabian Madurai
sumber