fix: widen scale adjust workspace guard

This commit is contained in:
134 2026-06-23 20:10:45 +08:00
parent 89b4a82e62
commit d93a0d06d5

View File

@ -425,6 +425,41 @@ function expandRectWithMargins(
};
}
function getRectUnion(
leftRect: NormalizedLocalEditRegion["rect"],
rightRect: NormalizedLocalEditRegion["rect"]
) {
const left = Math.min(leftRect.x, rightRect.x);
const top = Math.min(leftRect.y, rightRect.y);
const right = Math.max(
leftRect.x + leftRect.width,
rightRect.x + rightRect.width
);
const bottom = Math.max(
leftRect.y + leftRect.height,
rightRect.y + rightRect.height
);
return {
x: clamp(left, 0, 1),
y: clamp(top, 0, 1),
width: Math.max(0.001, clamp(right, 0, 1) - clamp(left, 0, 1)),
height: Math.max(0.001, clamp(bottom, 0, 1) - clamp(top, 0, 1)),
};
}
function rectsDifferMeaningfully(
leftRect: NormalizedLocalEditRegion["rect"],
rightRect: NormalizedLocalEditRegion["rect"],
epsilon = 0.0005
) {
return (
Math.abs(leftRect.x - rightRect.x) > epsilon ||
Math.abs(leftRect.y - rightRect.y) > epsilon ||
Math.abs(leftRect.width - rightRect.width) > epsilon ||
Math.abs(leftRect.height - rightRect.height) > epsilon
);
}
function getScaleAdjustWorkspaceRect(
sourceRect: NormalizedLocalEditRegion["rect"],
targetRect: NormalizedLocalEditRegion["rect"],
@ -432,37 +467,55 @@ function getScaleAdjustWorkspaceRect(
) {
const sourceWidth = Math.max(0.0001, sourceRect.width);
const sourceHeight = Math.max(0.0001, sourceRect.height);
const widthGrowthRatio = Math.max(0, targetRect.width / sourceWidth - 1);
const heightGrowthRatio = Math.max(0, targetRect.height / sourceHeight - 1);
const areaGrowthRatio = Math.max(
0,
const widthDeltaRatio = Math.abs(targetRect.width / sourceWidth - 1);
const heightDeltaRatio = Math.abs(targetRect.height / sourceHeight - 1);
const areaDeltaRatio = Math.abs(
Math.sqrt(
Math.max(0.0001, targetRect.width * targetRect.height) /
Math.max(0.0001, sourceWidth * sourceHeight)
) - 1
);
const explicitGrowthRatio = Math.max(
widthGrowthRatio,
heightGrowthRatio,
areaGrowthRatio
const sourceCenterX = sourceRect.x + sourceRect.width / 2;
const sourceCenterY = sourceRect.y + sourceRect.height / 2;
const targetCenterX = targetRect.x + targetRect.width / 2;
const targetCenterY = targetRect.y + targetRect.height / 2;
const movementRatioX = Math.abs(targetCenterX - sourceCenterX) / sourceWidth;
const movementRatioY = Math.abs(targetCenterY - sourceCenterY) / sourceHeight;
const explicitChangeRatio = Math.max(
widthDeltaRatio,
heightDeltaRatio,
areaDeltaRatio,
movementRatioX,
movementRatioY
);
const fallbackScaleRatio =
typeof scalePercent === "number" && Number.isFinite(scalePercent)
? Math.min(1, Math.max(0, scalePercent / 100))
? Math.min(1, Math.abs(scalePercent) / 100)
: 0;
const scaleRatio = Math.max(explicitGrowthRatio, fallbackScaleRatio);
if (scaleRatio <= 0) return targetRect;
const changeRatio = Math.max(explicitChangeRatio, fallbackScaleRatio);
const unionRect = getRectUnion(sourceRect, targetRect);
if (changeRatio <= 0 && !rectsDifferMeaningfully(unionRect, targetRect)) {
return targetRect;
}
const marginX = Math.min(
0.12,
Math.max(0.018, sourceRect.width * scaleRatio * 0.22)
0.16,
Math.max(
0.018,
unionRect.width * 0.04,
sourceRect.width * changeRatio * 0.24
)
);
const marginY = Math.min(
0.12,
Math.max(0.018, sourceRect.height * scaleRatio * 0.22)
0.16,
Math.max(
0.018,
unionRect.height * 0.04,
sourceRect.height * changeRatio * 0.24
)
);
return expandRectWithMargins(targetRect, marginX, marginY);
return expandRectWithMargins(unionRect, marginX, marginY);
}
function buildScaleAdjustCompositeRegions(
@ -476,8 +529,8 @@ function buildScaleAdjustCompositeRegions(
targetRect,
scalePercent
);
return workspaceRect.width > targetRect.width ||
workspaceRect.height > targetRect.height
return rectsDifferMeaningfully(workspaceRect, targetRect) &&
rectsDifferMeaningfully(workspaceRect, region.rect)
? [region.rect, targetRect, workspaceRect]
: [region.rect, targetRect];
});