fix: stuck resizing when resizing bound text container very fast beyond threshold (#4804)
* fix: stuck resizing when resizing bound text container very fast beyond threshold * fix * fix
This commit is contained in:
parent
0896892f8a
commit
4604c8d823
@ -35,6 +35,7 @@ import {
|
||||
import { Point, PointerDownState } from "../types";
|
||||
import Scene from "../scene/Scene";
|
||||
import {
|
||||
getApproxMinLineHeight,
|
||||
getApproxMinLineWidth,
|
||||
getBoundTextElement,
|
||||
getBoundTextElementId,
|
||||
@ -429,8 +430,6 @@ export const resizeSingleElement = (
|
||||
element.height,
|
||||
);
|
||||
|
||||
const boundTextElementId = getBoundTextElementId(element);
|
||||
|
||||
const boundsCurrentWidth = esx2 - esx1;
|
||||
const boundsCurrentHeight = esy2 - esy1;
|
||||
|
||||
@ -453,6 +452,9 @@ export const resizeSingleElement = (
|
||||
if (transformHandleDirection.includes("n")) {
|
||||
scaleY = (startBottomRight[1] - rotatedPointer[1]) / boundsCurrentHeight;
|
||||
}
|
||||
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
|
||||
// Linear elements dimensions differ from bounds dimensions
|
||||
const eleInitialWidth = stateAtResizeStart.width;
|
||||
const eleInitialHeight = stateAtResizeStart.height;
|
||||
@ -482,6 +484,13 @@ export const resizeSingleElement = (
|
||||
}
|
||||
}
|
||||
|
||||
if (boundTextElement) {
|
||||
const minWidth = getApproxMinLineWidth(getFontString(boundTextElement));
|
||||
const minHeight = getApproxMinLineHeight(getFontString(boundTextElement));
|
||||
eleNewWidth = Math.ceil(Math.max(eleNewWidth, minWidth));
|
||||
eleNewHeight = Math.ceil(Math.max(eleNewHeight, minHeight));
|
||||
}
|
||||
|
||||
const [newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2] =
|
||||
getResizedElementAbsoluteCoords(
|
||||
stateAtResizeStart,
|
||||
@ -491,11 +500,6 @@ export const resizeSingleElement = (
|
||||
const newBoundsWidth = newBoundsX2 - newBoundsX1;
|
||||
const newBoundsHeight = newBoundsY2 - newBoundsY1;
|
||||
|
||||
// don't allow resize to negative dimensions when text is bounded to container
|
||||
if ((newBoundsWidth < 0 || newBoundsHeight < 0) && boundTextElementId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate new topLeft based on fixed corner during resize
|
||||
let newTopLeft = [...startTopLeft] as [number, number];
|
||||
if (["n", "w", "nw"].includes(transformHandleDirection)) {
|
||||
@ -588,13 +592,9 @@ export const resizeSingleElement = (
|
||||
],
|
||||
});
|
||||
}
|
||||
let minWidth = 0;
|
||||
const boundTextElement = getBoundTextElement(element);
|
||||
if (boundTextElement) {
|
||||
minWidth = getApproxMinLineWidth(getFontString(boundTextElement));
|
||||
}
|
||||
|
||||
if (
|
||||
resizedElement.width >= minWidth &&
|
||||
resizedElement.width !== 0 &&
|
||||
resizedElement.height !== 0 &&
|
||||
Number.isFinite(resizedElement.x) &&
|
||||
Number.isFinite(resizedElement.y)
|
||||
|
@ -144,6 +144,7 @@ export const handleBindTextResize = (
|
||||
}
|
||||
|
||||
const updatedY = element.y + containerHeight / 2 - nextHeight / 2;
|
||||
|
||||
mutateElement(textElement, {
|
||||
text,
|
||||
// preserve padding and set width correctly
|
||||
@ -355,6 +356,7 @@ export const charWidth = (() => {
|
||||
const width = getTextWidth(char, font);
|
||||
cachedCharWidth[font][ascii] = width;
|
||||
}
|
||||
|
||||
return cachedCharWidth[font][ascii];
|
||||
};
|
||||
|
||||
@ -367,14 +369,14 @@ export const charWidth = (() => {
|
||||
};
|
||||
})();
|
||||
export const getApproxMinLineWidth = (font: FontString) => {
|
||||
const minCharWidth = getMinCharWidth(font);
|
||||
if (minCharWidth === 0) {
|
||||
const maxCharWidth = getMaxCharWidth(font);
|
||||
if (maxCharWidth === 0) {
|
||||
return (
|
||||
measureText(DUMMY_TEXT.split("").join("\n"), font).width +
|
||||
BOUND_TEXT_PADDING * 2
|
||||
);
|
||||
}
|
||||
return minCharWidth + BOUND_TEXT_PADDING * 2;
|
||||
return maxCharWidth + BOUND_TEXT_PADDING * 2;
|
||||
};
|
||||
|
||||
export const getApproxMinLineHeight = (font: FontString) => {
|
||||
@ -391,6 +393,15 @@ export const getMinCharWidth = (font: FontString) => {
|
||||
return Math.min(...cacheWithOutEmpty);
|
||||
};
|
||||
|
||||
export const getMaxCharWidth = (font: FontString) => {
|
||||
const cache = charWidth.getCache(font);
|
||||
if (!cache) {
|
||||
return 0;
|
||||
}
|
||||
const cacheWithOutEmpty = cache.filter((val) => val !== undefined);
|
||||
return Math.max(...cacheWithOutEmpty);
|
||||
};
|
||||
|
||||
export const getApproxCharsToFitInWidth = (font: FontString, width: number) => {
|
||||
// Generally lower case is used so converting to lower case
|
||||
const dummyText = DUMMY_TEXT.toLocaleLowerCase();
|
||||
|
Loading…
x
Reference in New Issue
Block a user