Say I have an SVG element containing some stuff:
<div style="margin-left:50px; width: 100%; min-height: 400px;">
<svg>
<g transform="translate(34.34,47.5) scale(0.345)" height="100%" width="100%">
<svg x="20" y ="50" style="overflow: visible">
<circle cx="0" cy="0" r="35" stroke="red" fill="blue">
<text>a bunch of text</text>
</svg>
<line />
</g>
<svg>
<div>
I'm trying to find the center position of the <g>
relative to the viewport of the outer <svg>
element, so that I can translate the <g>
to be centered within the outer <svg>
, and scale it to fit.
I was able to get it working using getBoundingClientRect()
and adjusting for the transform scale, but this does not work in Firefox because the <svg>
elements inside the <g>
container are not constrained to the bounding box of the displayed section of their contents (rather it's the same size as the outer <svg>
, with some scaling).
There is probably a solution using createSVGPoint()
and getScreenCTM()
or getCTM()
but frankly I'm not sure what I should be using.
An SVG without a viewBox attribute has a width of 300px and a height of 150px. I've added a
viewBox="0 0 300 150"
. You can remove it.Also I've added a rectangle to be able to see the position and the size of the
<g>
element. You can remove it as well.How I would center the
<g>
element: Since the<g>
element is transformed the easiest way to get it's size and position would be wrapping the<g>
element in another one, in this case<g id="wrap">
Next I can get the bounding box of the wrap:wrap.getBBox()
In order to center the wrap I need to know the center of the main svg canvas: x = 300/2; y=150/2. Now I can translate the wrap into the center
I hope this is what you were asking.
I managed to figure out a solution using one of the
d3.zoom
transform methods (we're using d3.zoom to manage the translate/scale transform), andSVGElement.getBBox()
. I originally was using this method but had messed up the calculation; this way it works though.