How Do I Get An Internal Svg Element's Position Relative To The Viewport Of An Outer Svg Element?
Say I have an SVG element containing some stuff:
Solution 2:
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), and SVGElement.getBBox()
. I originally was using this method but had messed up the calculation; this way it works though.
const selection = d3.select(group);
const zoomBehavior = d3.zoom().on('zoom', () => {
selectionTransform = d3.event.transform;
});
selection.call(zoomBehavior);
constscaleAndTransformTo = () => {
selection.call(zoomBehavior.translateBy, Math.random() * 100, Math.random() * 150);
group.setAttribute("transform", selectionTransform.toString());
}
scaleAndTransformTo();
reset.addEventListener('click', scaleAndTransformTo);
run.addEventListener('click', () => {
const { width: containerWidth, height: containerHeight } = container.getBoundingClientRect();
const containerCenter = [containerWidth / 2, containerHeight / 2];
const { height, width, x, y } = group.getBBox();
const nodeBBoxCenter = [x + (width / 2), y + (height / 2)];
// Apply the current interpolated translate/scale to the BBox center to get the actual positionconst groupCenterCoords = selectionTransform.apply(nodeBBoxCenter);
const translationOffset = [
(containerCenter[0] - groupCenterCoords[0]) / selectionTransform.k,
(containerCenter[1] - groupCenterCoords[1]) / selectionTransform.k,
];
selection.call(zoomBehavior.translateBy, ...translationOffset);
group.setAttribute("transform", selectionTransform.toString());
});
#page {
display: flex;
flex-direction: column;
position: relative;
align-items: stretch;
margin-left: 100px;
}
#container {
background-color: grey;
flex-grow: 1;
flex-shrink: 0;
min-height: 500px;
border: 1px solid red;
}
#group > svg {
overflow: visible;
}
#group > svg > circle {
overflow: visible;
}
text {
fill: black;
}
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script><divid="page"><div><buttonid="run">Run</button><buttonid="reset">Reset</button></div><svgid="container"><gx="0"y="0"id="group"width="100%"height="100%"><linex1="20"y1="50"x2="150"y2="150"stroke="brown" /><svgx="20"y ="50"><circlecx="0"cy="0"r="35"stroke="red"fill="blue"><textx="35"y="0"height="100%"width="100%">a bunch of text</text></svg><linex1="100"y1="350"x2="160"y2="340"stroke="brown" /><svgx="100"y ="350"><circlecx="0"cy="0"r="35"stroke="red"fill="blue"><textx="35"y="0"height="100%"width="100%">a bunch of text 3</text></svg></g><svg><div>
Post a Comment for "How Do I Get An Internal Svg Element's Position Relative To The Viewport Of An Outer Svg Element?"