避免超大缩放让网格步长计算死循环

previewGrid.ts 的 resolvePreviewGridStep 在 screenSpacing 溢出成 Infinity 时直接回基础步长:原先第二个 while 里 Infinity/2 仍是 Infinity,画布会卡死
previewWorkspaceZoom.test.tsx 补 Number.MAX_VALUE 缩放的回退用例
This commit is contained in:
2026-09-24 16:02:10 +08:00
parent 9e49db419f
commit 12e8287f92
2 changed files with 12 additions and 0 deletions
@@ -14,6 +14,11 @@ export function resolvePreviewGridStep(viewportScale: number): number {
let step = PREVIEW_GRID_BASE_STEP;
let screenSpacing = step * viewportScale;
// 极大缩放下 step * scale 会溢出成 Infinity,而 Infinity / 2 仍是 Infinity
// 下面两个 while 会因此永不收敛,这里先退回基础步长。
if (!Number.isFinite(screenSpacing)) {
return PREVIEW_GRID_BASE_STEP;
}
while (screenSpacing < PREVIEW_GRID_MIN_SCREEN_SPACING) {
step *= 2;
screenSpacing *= 2;
@@ -128,6 +128,13 @@ describe('PreviewWorkspace quick zoom', () => {
}
});
it('falls back to the base step when the screen spacing overflows', () => {
// 溢出成 Infinity 时步长无法收敛:必须直接回基础步长,不能死循环。
expect(resolvePreviewGridStep(Number.MAX_VALUE)).toBe(
PREVIEW_GRID_BASE_STEP,
);
});
it('applies the adaptive screen-space spacing to the preview background', () => {
const rendered = render(<PreviewWorkspace canvas={createCanvas()} />);
const preview = screen.getByRole('region', { name: 'UI 预览画布' });