Skip to content

Commit 14ccd43

Browse files
authored
fix(trace-viewer): prevent browser snapshot from moving out of bounds on host resize (#38048)
1 parent b7980a7 commit 14ccd43

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

packages/trace-viewer/src/ui/snapshotTab.tsx

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -189,41 +189,53 @@ export const SnapshotView: React.FunctionComponent<{
189189
</div>;
190190
};
191191

192+
const kWindowHeaderHeight = 40;
193+
const kMinBrowserFrameScaledWidth = 100;
194+
const kMinBrowserFrameScaledHeight = 60;
195+
192196
const SnapshotWrapper: React.FunctionComponent<React.PropsWithChildren<{
193197
snapshotInfo: SnapshotInfo,
194198
}>> = ({ snapshotInfo, children }) => {
195199
const [measure, ref] = useMeasure<HTMLDivElement>();
196200

197-
const windowHeaderHeight = 40;
198201
const snapshotContainerSize = {
199202
width: snapshotInfo.viewport.width,
200203
height: snapshotInfo.viewport.height,
201204
};
202205

203-
const renderedBrowserFrameSize = {
206+
const renderedBrowserExpectedFrameSize = {
204207
width: Math.max(snapshotContainerSize.width, 480),
205-
height: Math.max(snapshotContainerSize.height + windowHeaderHeight, 320),
208+
height: Math.max(snapshotContainerSize.height + kWindowHeaderHeight, 320),
206209
};
207210

208-
const scale = Math.min(measure.width / renderedBrowserFrameSize.width, measure.height / renderedBrowserFrameSize.height, 1);
211+
// Calculate ideal size for the snapshot size (including browser frame) to fit within the bounds
212+
const idealScale = Math.min(measure.width / renderedBrowserExpectedFrameSize.width, measure.height / renderedBrowserExpectedFrameSize.height, 1);
213+
// Prevent window from scaling below a minimum size
214+
const actualWidth = Math.max(idealScale * renderedBrowserExpectedFrameSize.width, kMinBrowserFrameScaledWidth);
215+
const actualHeight = Math.max(idealScale * renderedBrowserExpectedFrameSize.height, kMinBrowserFrameScaledHeight);
216+
// Using new minimum sizes, calculate the final scale
217+
const actualScale = Math.min(actualWidth / renderedBrowserExpectedFrameSize.width, actualHeight / renderedBrowserExpectedFrameSize.height);
209218
const translate = {
210-
x: (measure.width - renderedBrowserFrameSize.width) / 2,
211-
y: (measure.height - renderedBrowserFrameSize.height) / 2,
219+
// Don't let the browser clip out of bounds when it's at the min size
220+
x: (Math.max(measure.width, kMinBrowserFrameScaledWidth) - renderedBrowserExpectedFrameSize.width) / 2,
221+
y: (Math.max(measure.height, kMinBrowserFrameScaledHeight) - renderedBrowserExpectedFrameSize.height) / 2,
212222
};
213223

214-
return <div ref={ref} className='snapshot-wrapper'>
215-
<div className='snapshot-container' style={{
216-
width: renderedBrowserFrameSize.width + 'px',
217-
height: renderedBrowserFrameSize.height + 'px',
218-
transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})`,
219-
}}>
220-
<BrowserFrame url={snapshotInfo.url} />
221-
<div className='snapshot-browser-body'>
222-
<div style={{
223-
width: snapshotContainerSize.width + 'px',
224-
height: snapshotContainerSize.height + 'px',
225-
}}>
226-
{children}
224+
return <div className='snapshot-wrapper'>
225+
<div ref={ref} className='snapshot-content-measure'>
226+
<div className='snapshot-container' style={{
227+
width: renderedBrowserExpectedFrameSize.width + 'px',
228+
height: renderedBrowserExpectedFrameSize.height + 'px',
229+
transform: `translate(${translate.x}px, ${translate.y}px) scale(${actualScale})`,
230+
}}>
231+
<BrowserFrame url={snapshotInfo.url} />
232+
<div className='snapshot-browser-body'>
233+
<div style={{
234+
width: snapshotContainerSize.width + 'px',
235+
height: snapshotContainerSize.height + 'px',
236+
}}>
237+
{children}
238+
</div>
227239
</div>
228240
</div>
229241
</div>

0 commit comments

Comments
 (0)