Prostokąty ograniczające SVG: mierz we właściwych współrzędnych
Porównaj getBBox i getBoundingClientRect na przekształconej grafice SVG. Prawidłowo umieszczaj nakładki, sprawdzaj granice obrysu i dopasuj viewBox z jawnym marginesem.
Na tej stronie
- Wybierz pomiar odpowiedni dla miejsca docelowego
- Zmierz oryginalny przekształcony emblemat
- Narysuj każdą ramkę w jej własnym układzie współrzędnych
- Sprawdzaj opcje obrysu, zamiast zakładać ich obsługę
- Przelicz lokalny prostokąt przed dopasowaniem viewBox głównego elementu
- Mierz geometrię, którą zamierzasz edytować
- Najczęściej zadawane pytania
- Źródła
Użyj getBBox(), gdy potrzebujesz granic elementu SVG w jego własnych współrzędnych użytkownika. Użyj getBoundingClientRect(), gdy potrzebujesz prostokąta w pikselach CSS względem obszaru widoku przeglądarki. Zanim skopiujesz którykolwiek z tych wyników do nakładki lub viewBox, sprawdź, jakiego układu współrzędnych używa miejsce docelowe.
Obrócony emblemat może mieć mały lokalny prostokąt ograniczający i znacznie większy prostokąt wyrównany do ekranu. Oba pomiary mogą być prawidłowe. Żadnego z nich nie należy traktować jako uniwersalnego prostokąta obejmującego każdy narysowany piksel, zwłaszcza gdy w grę wchodzą obrysy, znaczniki, przycinanie lub filtry.
Wybierz pomiar odpowiedni dla miejsca docelowego
| Miejsce docelowe | Pomiar wyjściowy | Na co uważać |
|---|---|---|
| Prostokąt w tym samym układzie współrzędnych SVG | getBBox() | Nadaj prostokątowi zgodny kontekst przekształceń |
| Ramka zaznaczenia w HTML z pozycjonowaniem stałym | getBoundingClientRect() | Utrzymuj ją we współrzędnych obszaru widoku i aktualizuj, gdy zmienia się układ strony |
| viewBox głównego elementu SVG obejmujący przekształconą grupę | Lokalny prostokąt i przekształcenie współrzędnych | Przed dopasowaniem przelicz wartości na jednostki użytkownika głównego elementu |
| Przycięcie uwzględniające obrysy i efekty | Osobno zweryfikowana procedura wyznaczania granic | Nie zakładaj, że podstawowy prostokąt geometrii obejmuje wszystko, co zostało narysowane |
Dokumentacja MDN getBBox() documentation opisuje lokalne granice geometrii oraz opcjonalne ustawienia uwzględniania obrysu, znaczników i przycinania. Własne przekształcenie mierzonego elementu i przekształcenia jego przodków nie są uwzględniane w tym lokalnym wyniku. Elementy potomne grupy nadal współtworzą jej geometrię, wraz ze swoim rozmieszczeniem wewnątrz niej.
Dokumentacja MDN getBoundingClientRect() reference opisuje współrzędne względem obszaru widoku. Przewijanie zmienia tę relację współrzędnych. Wartości wyrażone w pikselach CSS nie stają się automatycznie jednostkami użytkownika SVG ani fizycznymi wymiarami wydruku.

Zmierz oryginalny przekształcony emblemat
Ten przykład testowy zawiera turkusowy pierścień z prostokątnym otworem oraz osobny złoty trójkąt. Obie figury mają gruby obrys z zaokrąglonymi łączeniami. Grupa jest przesunięta, obrócona i przeskalowana.
<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>Lokalne współrzędne rozciągają się od 0 do 140 w poziomie i od 0 do 60 w pionie. Otwór wpływa na wnętrze kształtu, ale nie zmniejsza tych zewnętrznych granic.
Otworzyliśmy tę geometrię w Chrome i zmierzyliśmy ją za pomocą niewielkiego skryptu testowego. Przy rozmiarze wyświetlania 600 × 300 pikseli CSS metoda getBBox() zwróciła x=0, y=0, width=140, height=60. Prostokąt względem obszaru widoku miał około 365.376 × 272.508 pikseli CSS. Jego położenie na ekranie zależało od umiejscowienia SVG na stronie.
Po zmianie rozmiaru wyświetlania na 300 × 150 lokalny prostokąt nadal miał 140 × 60. Prostokąt względem obszaru widoku miał teraz około 182.688 × 136.254, czyli połowę poprzednich wymiarów. Geometria źródłowa się nie zmieniła; zmieniło się jej odwzorowanie na stronie.
Te liczby opisują ten przykład testowy w sprawdzonej przeglądarce. Nie są porównaniem silników przeglądarek ani specyfikacją ramki zaznaczenia w każdym edytorze.
Narysuj każdą ramkę w jej własnym układzie współrzędnych
W przypadku lokalnej ramki użyj zwróconych współrzędnych i tego samego przekształcenia co dla mierzonej grupy. Umieść ją jako element równorzędny, aby nie została uwzględniona w następnym pomiarze:
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);Takie bezpośrednie skopiowanie przekształcenia jest odpowiednie dla tego przykładu testowego, ponieważ grafika i ramka mają tego samego rodzica. Prostokąt wstawiony w innym miejscu wymaga macierzy odwzorowania między dwoma układami współrzędnych.
W przypadku ramki HTML umieść div bezpośrednio w body, z pozycjonowaniem stałym i bez przekształconego przodka wyznaczającego blok zawierający:
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`,
});Tutaj overlay to Twój istniejący element ramki. Wykonuj pomiar ponownie przy przewijaniu, zmianie rozmiaru lub zmianie układu bądź przekształcenia grafiki. Jeśli zamiast tego pozycjonujesz względem dokumentu, uwzględnij przesunięcia przewijania; jeśli używasz pozycjonowanego kontenera, uwzględnij jego układ współrzędnych. Mieszanie tych zasad rozmieszczania często sprawia, że prawidłowo zmierzony prostokąt wygląda na przesunięty.
Nasz skrypt testowy wyświetlał obie ramki. Lokalny prostokąt przechylał się wraz z pierścieniem i trójkątem, natomiast przerywany prostokąt HTML zachowywał poziome i pionowe krawędzie. Gruby obrys wystawał poza niektóre fragmenty ramek wyznaczających granice geometrii.
Sprawdzaj opcje obrysu, zamiast zakładać ich obsługę
Domyślny lokalny prostokąt nie uwzględnia szerokości obrysu. MDN dokumentuje getBBox({ stroke: true }), ale obsługę parametru opcji w przeglądarkach trzeba sprawdzać osobno od obsługi od dawna dostępnej metody bez argumentów.
W naszym przykładzie testowym w Chrome przekazanie { stroke: true } zwróciło ten sam prostokąt 140 × 60 co wywołanie bez argumentów. Usunięcie obrysu o szerokości 10 jednostek również nie zmieniło prostokąta względem obszaru widoku. Widoczne ciemne obramowanie wyraźnie się zmieniło, więc żaden z wyników tego testu nie odpowiadał pełnemu obszarowi zajmowanemu przez narysowaną grafikę.
Samo przyjęcie obiektu opcji bez zgłoszenia wyjątku nie dowodzi, że wywołanie uwzględniło opcję. Przetestuj znany kształt z obrysem i sprawdź zwrócone wymiary w docelowej przeglądarce. Skorzystaj z SVG bounding-box definitions, aby rozróżnić granice obiektu, obrysu i geometrii z dekoracjami.
Nie stosuj reguły marginesu równego połowie szerokości obrysu do każdego kształtu. Łączenia ostre, znaczniki, obrysy niepodlegające skalowaniu, cienie i filtry mogą wystawać w różny sposób. W przypadku prostego przykładu testowego z zaokrąglonymi łączeniami, nad którym masz kontrolę, jawny margines i kontrola wizualna mogą wystarczyć. Automatyczne narzędzie do przycinania przy eksporcie wymaga celowej obsługi tych przypadków.
Przelicz lokalny prostokąt przed dopasowaniem viewBox głównego elementu
Nigdy nie wklejaj wartości x, y, width i height prostokąta względem obszaru widoku bezpośrednio do viewBox SVG. Te wartości uwzględniają położenie na stronie i używają innego układu jednostek.
W tym przykładzie testowym odwzoruj cztery narożniki lokalnego prostokąta na współrzędne użytkownika głównego elementu SVG. Dokumentacja MDN getScreenCTM() reference opisuje macierz używaną do odwzorowania współrzędnych SVG na obszar widoku dokumentu. Połączenie macierzy grafiki z odwrotnością macierzy głównego elementu usuwa to wspólne odwzorowanie ekranowe:
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(" "));Zakładamy tutaj, że SVG jest renderowany, a przekształcenia dwuwymiarowe są odwracalne. Odwzorowanie narożników lokalnego prostokąta daje wyrównany do osi prostokąt obejmujący przekształconą geometrię, ale niekoniecznie najmniejszy możliwy prostokąt wokół każdej przekształconej krzywej.
Z tym marginesem skrypt testowy wyznaczył viewBox o wartości około 57.571 23 206.688 160.254. Sprawdziliśmy wynik i zaokrąglony obrys przykładu testowego pozostał wewnątrz obszaru wyświetlania. Przy szerokim obszarze wyświetlania nadal pozostawało wolne miejsce po bokach, ponieważ dopasowany viewBox miał inne proporcje; dopasowanie nie oznacza rozciągania.
Jeśli potrzebujesz punktu obrotu zamiast przycięcia, poradnik dotyczący transform-origin wyjaśnia, jak prostokąty odniesienia wpływają na obrót. W przypadku fizycznych wymiarów przy imporcie skorzystaj z procedury rozwiązywania problemów z rozmiarem SVG.
Mierz geometrię, którą zamierzasz edytować
Jeśli Twój materiał źródłowy istnieje tylko jako PNG lub JPG i potrzebujesz edytowalnych kształtów, PerfectVector może odtworzyć SVG przed pomiarem. Sprawdź jego ścieżki, otwory, obrysy i wszelką zachowaną zawartość rastrową. Prostokąt ograniczający pokazuje, dokąd sięga geometria; nie dowodzi, że wektoryzacja jest dokładna ani że każdy widoczny szczegół da się edytować.
Istniejący SVG możesz zmierzyć bezpośrednio. Poradnik edycji SVG pomaga rozpoznać, z czym faktycznie pracujesz, a omówienie wektoryzacji obrazów wyjaśnia wcześniejszy etap konwersji.
W przypadku grafiki dostępnej wyłącznie jako obraz rastrowy wypróbuj swój materiał źródłowy w PerfectVector, sprawdź odtworzone kontury, a następnie zmierz grupę, którą umieścisz lub wyeksportujesz. Zachowaj margines i sprawdź ostateczne widoczne krawędzie, zanim uznasz wynik za przycięcie gotowe do przekazania.
Najczęściej zadawane pytania
Dlaczego te dwie metody zwracają różne szerokości? Używają różnych układów współrzędnych. Lokalny prostokąt SVG opisuje geometrię w jednostkach użytkownika, a prostokąt względem obszaru widoku opisuje jej granice w pikselach CSS po odwzorowaniu na stronę. Skalowanie i obrót mogą zmieniać te wymiary.
Czy prostokąt ograniczający mówi mi, czy grafika ma otwór? Nie. Prostokąt zapisuje zewnętrzne granice, a nie wewnętrzną topologię. Pełny prostokąt i pierścień o tych samych zewnętrznych krawędziach mogą mieć taki sam prostokąt ograniczający. Sprawdź ścieżki i reguły wypełnienia, aby zweryfikować otwory.
Czy mogę użyć prostokąta względem obszaru widoku jako viewBox? Nie bezpośrednio. Najpierw przelicz odpowiednią geometrię na współrzędne użytkownika głównego elementu SVG. Nie kopiuj położenia na ekranie i wymiarów w pikselach CSS do prostokąta we współrzędnych źródłowych.
Źródła
- MDN getBBox — Definiuje lokalne granice SVG i opcjonalne ustawienia pomiaru.
- MDN getBoundingClientRect — Wyjaśnia prostokąty względem obszaru widoku oraz wpływ przewijania.
- SVG bounding-box definitions — Rozróżnia granice obiektu, obrysu i geometrii z dekoracjami.
- MDN getScreenCTM — Dokumentuje macierz używaną do łączenia współrzędnych SVG i obszaru widoku.
Więcej z bloga

Kolejność transformacji SVG: skalowanie i pozycjonowanie grafiki
Porównaj kolejność translate i scale w SVG na przykładzie logo z pomiarami. Użyj zagnieżdżonych grup, prześledź jeden punkt i ustaw grafikę bez zmieniania jej źródłowych ścieżek.

Obrazy SVG w Graphviz: zadbaj o przenośność grafiki węzłów
Dodaj grafikę SVG do węzła Graphviz, sprawdź odwołanie do obrazu i przetestuj kompletny pakiet zasobów, porównując go z przeniesionym diagramem oraz samowystarczalną kopią do przekazania.