PerfectVector
Von Irene Kim8 Min. Lesezeit

SVG-Begrenzungsrahmen: Die richtigen Koordinaten messen

Vergleiche getBBox und getBoundingClientRect bei transformierter SVG-Grafik. Platziere Overlays korrekt, teste Konturgrenzen und passe eine viewBox mit ausdrücklich festgelegtem Rand an.

Auf dieser Seite

Verwende getBBox(), wenn du die Grenzen eines SVG-Elements in seinen eigenen Benutzerkoordinaten brauchst. Verwende getBoundingClientRect(), wenn du ein Rechteck in CSS-Pixeln relativ zum Browser-Viewport brauchst. Bevor du eines der Ergebnisse in ein Overlay oder eine viewBox kopierst, prüfe, welches Koordinatensystem das Ziel verwendet.

Ein gedrehtes Emblem kann eine kleine lokale Begrenzung und eine viel größere bildschirmausgerichtete Begrenzung haben. Beide Messungen können gültig sein. Keine sollte als universelles Rechteck um jeden gezeichneten Pixel verstanden werden, besonders wenn Konturen, Marker, Beschneidungen oder Filter beteiligt sind.

Wähle die Messung passend zum Ziel

ZielAusgangsmessungWorauf du achten musst
Rechteck innerhalb desselben SVG-KoordinatensystemsgetBBox()Dem Rechteck den passenden Transformationskontext geben
Feste HTML-AuswahlkonturgetBoundingClientRect()In Viewport-Koordinaten halten und bei Layoutänderungen aktualisieren
Wurzel-SVG-viewBox um eine transformierte GruppeLokale Begrenzung plus KoordinatentransformationVor dem Einpassen in Benutzereinheiten der Wurzel umrechnen
Zuschnitt einschließlich Konturen und EffektenSeparat geprüfter Ablauf zur GrenzermittlungNicht annehmen, dass eine einfache Geometriebegrenzung alle gezeichneten Bereiche einschließt

Die getBBox()-Dokumentation von MDN beschreibt lokale Geometriegrenzen und die optionalen Einstellungen für Konturen, Marker und Beschneidung. Die eigene Transformation des gemessenen Elements und die seiner Vorfahren sind im lokalen Ergebnis nicht enthalten. Die Nachfahren einer Gruppe tragen weiterhin zur Geometrie der Gruppe bei, einschließlich ihrer Platzierung innerhalb der Gruppe.

Die getBoundingClientRect()-Referenz von MDN beschreibt Viewport-relative Koordinaten. Scrollen ändert diese Koordinatenbeziehung. Diese CSS-Pixelwerte sind nicht automatisch SVG-Benutzereinheiten oder physische Druckabmessungen.

Illustration eines geneigten Emblems mit einem passend geneigten lokalen Rechteck innerhalb eines waagerechten Bildschirmrechtecks
Konzeptionelle Illustration zweier Koordinatensysteme. Ein lokales Rechteck folgt den Achsen der Grafik; ein Viewport-Rechteck bleibt am Bildschirm ausgerichtet.

Miss ein eigenes transformiertes Emblem

Diese Testgrafik enthält einen blaugrünen Ring mit rechteckiger Öffnung und ein separates goldenes Dreieck. Beide haben eine dicke Kontur mit runden Übergängen. Die Gruppe wird verschoben, gedreht und skaliert.

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

Die lokalen Koordinaten verlaufen horizontal von 0 bis 140 und vertikal von 0 bis 60. Das Loch beeinflusst das Innere der Form, verkleinert aber diese äußeren Ausdehnungen nicht.

Wir öffneten diese Geometrie in Chrome und maßen sie mit einem kleinen Testaufbau. Bei einer Darstellungsgröße von 600 × 300 CSS-Pixeln gab getBBox() x=0, y=0, width=140, height=60 zurück. Das Client-Rechteck war ungefähr 365,376 × 272,508 CSS-Pixel groß. Seine Bildschirmposition hing davon ab, wo das SVG auf der Seite lag.

Nach dem Ändern der Darstellungsgröße auf 300 × 150 blieb die lokale Begrenzung bei 140 × 60. Das Client-Rechteck wurde ungefähr 182,688 × 136,254 groß, also halb so groß wie zuvor. Die Quellgeometrie hatte sich nicht geändert, ihre Abbildung auf die Seite dagegen schon.

Diese Zahlen beschreiben diese Testgrafik im getesteten Browser. Sie sind kein Vergleich von Browser-Engines und keine Spezifikation für den Auswahlrahmen jedes Editors.

Zeichne jede Kontur in ihrem eigenen Koordinatensystem

Für eine lokale Kontur verwendest du die zurückgegebenen Koordinaten und dieselbe Transformation wie die gemessene Gruppe. Platziere sie als Geschwisterelement, damit sie nicht Teil der nächsten Messung wird:

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

Dieses direkte Kopieren der Transformation passt zu dieser Testgrafik, weil Grafik und Kontur denselben Elternknoten haben. Ein anderswo eingefügtes Rechteck benötigt eine Matrixabbildung zwischen den beiden Koordinatensystemen.

Für eine HTML-Kontur platzierst du ein div direkt unter body, mit fester Positionierung und ohne transformierten umgebenden Vorfahren:

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`,
});

Hier ist overlay dein vorhandenes Konturelement. Miss nach Scrollen, Größenänderungen oder Änderungen am Layout oder der Transformation der Grafik erneut. Wenn du stattdessen Dokumentpositionierung verwendest, berücksichtige Scrollversätze; bei einem positionierten Container berücksichtigst du dessen Koordinatensystem. Das Vermischen dieser Platzierungsregeln ist ein häufiger Grund dafür, dass ein ansonsten korrektes Rechteck verschoben erscheint.

Unser Testaufbau zeigte beide Konturen. Das lokale Rechteck neigte sich mit Ring und Dreieck, während das gestrichelte HTML-Rechteck waagerecht und senkrecht blieb. Die dicke Kontur ragte über Teile der Geometriebegrenzungen hinaus.

Teste Konturoptionen, statt Unterstützung vorauszusetzen

Die standardmäßige lokale Begrenzung schließt die Konturbreite aus. MDN dokumentiert getBBox({ stroke: true }), doch die Kompatibilität des Optionsparameters muss getrennt von der seit Langem etablierten Methode ohne Argument betrachtet werden.

Bei unserer Chrome-Testgrafik gab die Übergabe von { stroke: true } dieselbe Begrenzung von 140 × 60 zurück wie der Aufruf ohne Argument. Auch das Entfernen der 10 Einheiten breiten Kontur ließ das Client-Rechteck unverändert. Der sichtbare dunkle Rand änderte sich deutlich, also stellte in diesem Test keines der Ergebnisse die vollständige gezeichnete Ausdehnung dar.

Ein Aufruf, der ein Optionsobjekt akzeptiert, ohne einen Fehler auszulösen, beweist noch nicht, dass er die Option berücksichtigt hat. Teste eine bekannte Form mit Kontur und prüfe die zurückgegebenen Abmessungen in deinem Zielbrowser. Verwende die SVG-Definitionen für Begrenzungsrahmen, um Objekt-, Kontur- und dekorierte Grenzen zu unterscheiden.

Übertrage eine Randregel von einer halben Konturbreite nicht pauschal auf jede Form. Gehrungsübergänge, Marker, nicht skalierende Konturen, Schatten und Filter können sich unterschiedlich ausdehnen. Für eine einfache selbst kontrollierte Testgrafik mit runden Übergängen können ein expliziter Rand und visuelle Prüfung ausreichen. Ein automatischer Export-Zuschnitt muss diese Fälle gezielt behandeln.

Rechne eine lokale Begrenzung um, bevor du die Wurzel-viewBox einpasst

Kopiere x, y, width und height des Client-Rechtecks niemals direkt in die SVG-viewBox. Diese Werte enthalten die Seitenpositionierung und verwenden ein anderes Einheitensystem.

Bilde für die Testgrafik die vier Ecken ihrer lokalen Begrenzung in die Benutzerkoordinaten des Wurzel-SVG ab. Die getScreenCTM()-Referenz von MDN beschreibt die Matrix, die SVG-Koordinaten in Richtung Dokument-Viewport abbildet. Die Kombination der Grafikmatrix mit der inversen Wurzelmatrix entfernt diese gemeinsame Bildschirmabbildung:

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(" "));

Das setzt ein gerendertes SVG mit invertierbaren zweidimensionalen Transformationen voraus. Das Abbilden der Ecken eines lokalen Rechtecks liefert eine konservative achsenparallele Hülle, nicht unbedingt die engstmögliche Begrenzung um jede transformierte Kurve.

Der Testaufbau erzeugte mit diesem Rand eine viewBox von ungefähr 57.571 23 206.688 160.254. Wir prüften das Ergebnis, und die runde Kontur der Testgrafik blieb innerhalb des Darstellungsbereichs. Die breite Darstellung hatte weiterhin seitlichen Leerraum, weil die eingepasste viewBox ein anderes Seitenverhältnis hatte; Einpassen bedeutet nicht Strecken.

Wenn du statt eines Zuschnitts einen Drehpunkt brauchst, erklärt der transform-origin-Leitfaden, wie Referenzrahmen die Drehung beeinflussen. Für physische Importabmessungen verwende den Ablauf zur SVG-Größenfehlersuche.

Miss die Geometrie, die du bearbeiten möchtest

Wenn deine Quelle nur als PNG oder JPG vorliegt und du bearbeitbare Formen brauchst, kann PerfectVector vor der Messung ein SVG rekonstruieren. Prüfe seine Pfade, Öffnungen, Konturen und eventuell erhaltene Rasterinhalte. Ein Begrenzungsrahmen zeigt, wie weit sich Geometrie erstreckt; er beweist nicht, dass die Nachzeichnung genau oder jedes sichtbare Detail bearbeitbar ist.

Ein vorhandenes SVG lässt sich direkt messen. Der SVG-Bearbeitungsleitfaden hilft dabei, zu erkennen, was du tatsächlich hast, während der Überblick zur Bildvektorisierung den vorgelagerten Konvertierungsschritt erklärt.

Bei reiner Rastergrafik teste deine Quelle in PerfectVector, prüfe die rekonstruierten Konturen und miss dann die Gruppe, die du platzieren oder exportieren wirst. Behalte einen Rand und prüfe die endgültig sichtbaren Kanten, bevor du das Ergebnis als Zuschnitt für die Auslieferung verwendest.

FAQ

Warum geben die beiden Methoden unterschiedliche Breiten zurück? Sie verwenden unterschiedliche Koordinatensysteme. Die lokale SVG-Begrenzung beschreibt Geometrie in Benutzereinheiten, während das Client-Rechteck ihre Viewport-relativen Grenzen nach der Seitenabbildung in CSS-Pixeln beschreibt. Skalierung und Drehung können diese Abmessungen ändern.

Zeigt ein Begrenzungsrahmen, ob die Grafik ein Loch hat? Nein. Ein Rechteck erfasst äußere Ausdehnungen, nicht innere Topologie. Ein ausgefülltes Rechteck und ein Ring mit denselben Außenkanten können denselben Begrenzungsrahmen haben. Prüfe Pfade und Füllregeln, um Öffnungen zu kontrollieren.

Kann ich das Client-Rechteck als viewBox verwenden? Nicht direkt. Rechne die betreffende Geometrie zuerst in die Benutzerkoordinaten des Wurzel-SVG um. Bildschirmposition und CSS-Pixelabmessungen sollten nicht in ein Quellkoordinatenrechteck kopiert werden.

Quellen

  1. MDN getBBox — Definiert lokale SVG-Grenzen und die optionalen Messeinstellungen.
  2. MDN getBoundingClientRect — Erklärt Viewport-relative Rechtecke und Scrollen.
  3. SVG-Definitionen für Begrenzungsrahmen — Unterscheidet Objekt-, Kontur- und dekorierte Geometriegrenzen.
  4. MDN getScreenCTM — Dokumentiert die Matrix, die SVG- und Viewport-Koordinaten verbindet.

Mehr aus dem Blog

Starte mit einer sauberen SVG,
die leichter zu bearbeiten ist