Bounding Box SVG: Ukur Koordinat yang Tepat
Bandingkan getBBox dan getBoundingClientRect pada karya SVG yang ditransformasi. Tempatkan overlay, uji batas stroke, dan sesuaikan viewBox dengan margin eksplisit.
Di halaman ini
Gunakan getBBox() ketika Anda memerlukan batas elemen SVG dalam koordinat penggunanya sendiri. Gunakan getBoundingClientRect() ketika Anda memerlukan persegi panjang dalam piksel CSS relatif terhadap viewport browser. Sebelum menyalin salah satu hasil ke overlay atau viewBox, periksa sistem koordinat yang dipakai tujuan.
Lambang yang diputar dapat memiliki kotak lokal kecil dan kotak sejajar layar jauh lebih besar. Kedua pengukuran dapat valid. Keduanya tidak boleh dianggap sebagai persegi panjang universal di sekitar setiap piksel yang digambar, terutama ketika melibatkan stroke, marker, clipping, atau filter.
Pilih pengukuran untuk tujuan
| Tujuan | Pengukuran awal | Perhatian yang diperlukan |
|---|---|---|
| Persegi panjang dalam sistem koordinat SVG yang sama | getBBox() | Berikan konteks transformasi yang cocok pada persegi panjang |
| Outline seleksi HTML dengan posisi fixed | getBoundingClientRect() | Pertahankan dalam koordinat viewport dan perbarui saat tata letak berubah |
| ViewBox SVG akar di sekitar grup yang ditransformasi | Kotak lokal ditambah transformasi koordinat | Konversikan ke satuan pengguna akar sebelum menyesuaikan |
| Potongan yang mencakup stroke dan efek | Alur batas yang diverifikasi terpisah | Jangan menganggap kotak geometri dasar mencakup semua pewarnaan |
Dokumentasi getBBox() MDN menjelaskan batas geometri lokal dan kontrol opsional stroke, marker, serta clipping. Transformasi elemen yang diukur sendiri dan transformasi leluhurnya tidak disertakan dalam hasil lokal itu. Keturunan grup masih berkontribusi pada geometri grup, termasuk penempatannya di dalam grup.
Referensi getBoundingClientRect() MDN menjelaskan koordinat relatif terhadap viewport. Scrolling mengubah hubungan koordinat itu. Nilai piksel CSS tersebut tidak otomatis berupa satuan pengguna SVG atau dimensi cetak fisik.

Ukur lambang asli yang ditransformasi
Contoh ini berisi cincin hijau kebiruan dengan bukaan persegi panjang dan segitiga emas terpisah. Keduanya memiliki stroke tebal dengan sambungan round. Grup ditranslasikan, diputar, dan diskalakan.
<svg id="scene" width="600" height="300" viewBox="0 0 300 150"
xmlns="http://www.w3.org/2000/svg" style="overflow:visible">
<g id="art" transform="translate(100 35) rotate(25) scale(1.2)"
stroke="#17364c" stroke-width="10" stroke-linejoin="round">
<path fill="#147d78" fill-rule="evenodd"
d="M0 0H80V60H0Z M20 20H60V40H20Z" />
<path fill="#e5a340" d="M100 50L120 10L140 50Z" />
</g>
</svg>
<script>
const art = document.querySelector("#art");
const local = art.getBBox();
const screen = art.getBoundingClientRect();
</script>Koordinat lokal membentang dari 0 hingga 140 horizontal dan 0 hingga 60 vertikal. Lubang memengaruhi bagian dalam bentuk, tetapi tidak mengecilkan jangkauan luar tersebut.
Kami membuka geometri ini di Chrome dan mengukurnya dengan alat pengujian kecil. Pada ukuran tampilan 600 × 300 piksel CSS, getBBox() mengembalikan x=0, y=0, width=140, height=60. Client rectangle sekitar 365.376 × 272.508 piksel CSS. Posisi layarnya bergantung pada lokasi SVG dalam halaman.
Setelah mengubah ukuran tampilan menjadi 300 × 150, kotak lokal tetap 140 × 60. Client rectangle menjadi sekitar 182.688 × 136.254, setengah dimensi sebelumnya. Geometri sumber tidak berubah; pemetaannya ke halaman yang berubah.
Angka ini menjelaskan contoh tersebut dalam browser yang diuji. Angka bukan perbandingan mesin browser atau spesifikasi kotak seleksi setiap editor.
Gambar setiap outline dalam sistem koordinatnya sendiri
Untuk outline lokal, gunakan koordinat yang dikembalikan dan transformasi yang sama dengan grup terukur. Letakkan sebagai elemen saudara agar tidak menjadi bagian pengukuran berikutnya:
const scene = document.querySelector("#scene");
const box = art.getBBox();
const outline = document.createElementNS("http://www.w3.org/2000/svg", "rect");
for (const key of ["x", "y", "width", "height"]) {
outline.setAttribute(key, box[key]);
}
outline.setAttribute("transform", art.getAttribute("transform"));
outline.setAttribute("fill", "none");
outline.setAttribute("stroke", "olive");
scene.append(outline);Penyalinan transformasi langsung itu sesuai untuk contoh ini karena karya dan outline berbagi induk yang sama. Persegi panjang yang dimasukkan di tempat lain memerlukan pemetaan matriks antara kedua sistem koordinat.
Untuk outline HTML, letakkan div langsung di bawah body dengan posisi fixed dan tanpa leluhur pembatas yang ditransformasi:
const box = art.getBoundingClientRect();
Object.assign(overlay.style, {
position: "fixed",
boxSizing: "border-box",
pointerEvents: "none",
border: "2px dashed coral",
left: `${box.x}px`,
top: `${box.y}px`,
width: `${box.width}px`,
height: `${box.height}px`,
});Di sini overlay adalah elemen outline yang sudah ada. Ukur ulang ketika scrolling, mengubah ukuran, atau mengubah tata letak maupun transformasi karya. Jika memakai penempatan dokumen, perhitungkan offset scroll; jika memakai wadah yang diposisikan, perhitungkan sistem koordinat wadah itu. Mencampur aturan penempatan ini merupakan penyebab umum persegi panjang yang sebenarnya benar tampak bergeser.
Alat pengujian kami menampilkan kedua outline. Persegi panjang lokal miring bersama cincin dan segitiga, sementara persegi panjang HTML putus-putus tetap horizontal dan vertikal. Stroke tebal melampaui sebagian outline geometri.
Uji opsi stroke alih-alih menganggap dukungan tersedia
Kotak lokal default mengecualikan lebar stroke. MDN mendokumentasikan getBBox({ stroke: true }), tetapi parameter opsi memiliki pertimbangan kompatibilitas tersendiri, berbeda dari metode tanpa argumen yang sudah lama tersedia.
Dalam contoh Chrome kami, memberikan { stroke: true } mengembalikan kotak 140 × 60 yang sama dengan pemanggilan tanpa argumen. Menghapus stroke 10 satuan juga membiarkan client rectangle tetap sama. Border gelap yang terlihat jelas berubah, sehingga kedua hasil dalam pengujian itu tidak mewakili seluruh jangkauan area yang digambar.
Pemanggilan yang menerima objek opsi tanpa error belum cukup untuk membuktikan opsi tersebut dihormati. Uji bentuk dengan stroke yang diketahui dan periksa dimensi yang dikembalikan dalam browser target. Gunakan definisi bounding box SVG untuk membedakan batas objek, stroke, dan decorated.
Jangan menggeneralisasi aturan padding setengah stroke ke setiap bentuk. Sambungan miter, marker, stroke yang tidak diskalakan, bayangan, dan filter dapat meluas secara berbeda. Untuk contoh sederhana bersambungan round yang Anda kendalikan, margin eksplisit ditambah pemeriksaan visual mungkin cukup. Untuk alat pemotong ekspor otomatis, kasus itu memerlukan penanganan yang disengaja.
Konversikan kotak lokal sebelum menyesuaikan viewBox akar
Jangan pernah menempelkan x, y, width, dan height client rectangle langsung ke viewBox SVG. Nilai itu mencakup penempatan halaman dan memakai sistem satuan berbeda.
Untuk contoh, petakan keempat sudut kotak lokalnya ke koordinat pengguna SVG akar. Referensi getScreenCTM() MDN menjelaskan matriks yang dipakai untuk memetakan koordinat SVG menuju viewport dokumen. Menggabungkan matriks karya dengan matriks akar invers menghapus pemetaan layar bersama itu:
const box = art.getBBox();
const rootMatrix = scene.getScreenCTM();
const artMatrix = art.getScreenCTM();
if (!rootMatrix || !artMatrix) throw new Error("SVG is not measurable");
const toRoot = rootMatrix.inverse().multiply(artMatrix);
const corners = [
[box.x, box.y],
[box.x + box.width, box.y],
[box.x + box.width, box.y + box.height],
[box.x, box.y + box.height],
].map(([x, y]) => new DOMPoint(x, y).matrixTransform(toRoot));
const xs = corners.map(p => p.x);
const ys = corners.map(p => p.y);
const x = Math.min(...xs);
const y = Math.min(...ys);
const width = Math.max(...xs) - x;
const height = Math.max(...ys) - y;
const padding = 12; // Chosen for this simple fixture, in root user units.
scene.setAttribute("viewBox", [
x - padding, y - padding,
width + 2 * padding, height + 2 * padding,
].join(" "));Ini mengasumsikan SVG yang dirender dengan transformasi dua dimensi yang dapat diinvers. Memetakan sudut persegi panjang lokal memberikan batas pembungkus konservatif yang sejajar sumbu, belum tentu kotak paling rapat di sekitar setiap kurva yang ditransformasi.
Alat pengujian menghasilkan viewBox sekitar 57.571 23 206.688 160.254 dengan margin itu. Kami memeriksa hasil dan stroke round contoh tetap di dalam area tampilan. Tampilan lebar masih memiliki ruang samping karena viewBox yang disesuaikan memiliki rasio aspek berbeda; penyesuaian tidak berarti peregangan.
Jika Anda membutuhkan pivot alih-alih potongan, panduan transform-origin menjelaskan cara kotak referensi memengaruhi rotasi. Untuk dimensi impor fisik, gunakan alur masalah ukuran SVG.
Ukur geometri yang ingin Anda edit
Jika sumber hanya tersedia sebagai PNG atau JPG dan Anda membutuhkan bentuk yang bisa diedit, PerfectVector dapat merekonstruksi SVG sebelum pengukuran. Periksa path, bukaan, stroke, dan konten raster yang masih dipertahankan. Bounding box memberi tahu jangkauan geometri; tidak membuktikan tracing akurat atau setiap detail terlihat bisa diedit.
SVG yang ada dapat diukur langsung. Panduan penyuntingan SVG membantu mengidentifikasi apa yang sebenarnya Anda miliki, sementara ikhtisar vektorisasi gambar menjelaskan tahap konversi sebelumnya.
Untuk karya yang hanya raster, coba sumber Anda dalam PerfectVector, periksa kontur hasil rekonstruksi, lalu ukur grup yang akan ditempatkan atau diekspor. Sisakan margin dan periksa tepi terlihat akhir sebelum memperlakukan hasil sebagai potongan untuk diserahkan.
FAQ
Mengapa kedua metode mengembalikan lebar berbeda? Keduanya memakai sistem koordinat berbeda. Kotak SVG lokal menjelaskan geometri dalam satuan pengguna, sementara client rectangle menjelaskan batas relatif viewport dalam piksel CSS setelah pemetaan halaman. Penskalaan dan rotasi dapat mengubah dimensi tersebut.
Apakah bounding box memberi tahu apakah karya memiliki lubang? Tidak. Persegi panjang merekam jangkauan luar, bukan topologi bagian dalam. Persegi panjang solid dan cincin dengan tepi luar sama dapat memiliki bounding box sama. Periksa path dan aturan isian untuk memeriksa bukaan.
Bisakah saya memakai client rectangle sebagai viewBox? Tidak langsung. Konversikan geometri relevan ke koordinat pengguna SVG akar terlebih dahulu. Posisi layar dan dimensi piksel CSS tidak boleh disalin ke persegi panjang koordinat sumber.
Sources
- MDN getBBox — Mendefinisikan batas SVG lokal dan kontrol pengukuran opsional.
- MDN getBoundingClientRect — Menjelaskan persegi panjang relatif viewport dan scrolling.
- Definisi bounding box SVG — Membedakan batas geometri objek, stroke, dan decorated.
- MDN getScreenCTM — Mendokumentasikan matriks untuk menghubungkan koordinat SVG dan viewport.
Lebih banyak dari blog

Urutan Transformasi SVG: Skalakan dan Posisikan Karya
Bandingkan urutan translate dan scale SVG dengan contoh logo terukur. Gunakan grup bersarang, ikuti satu titik, dan tempatkan karya tanpa mengubah path sumber.

Gambar SVG Graphviz: Buat Karya Node Tetap Portabel
Tambahkan karya SVG pada node Graphviz, periksa referensi gambarnya, lalu uji paket aset lengkap, diagram yang dipindahkan, dan salinan mandiri untuk diserahkan.