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 { Point, PointerDownState } from "../types";
|
||||||
import Scene from "../scene/Scene";
|
import Scene from "../scene/Scene";
|
||||||
import {
|
import {
|
||||||
|
getApproxMinLineHeight,
|
||||||
getApproxMinLineWidth,
|
getApproxMinLineWidth,
|
||||||
getBoundTextElement,
|
getBoundTextElement,
|
||||||
getBoundTextElementId,
|
getBoundTextElementId,
|
||||||
@ -429,8 +430,6 @@ export const resizeSingleElement = (
|
|||||||
element.height,
|
element.height,
|
||||||
);
|
);
|
||||||
|
|
||||||
const boundTextElementId = getBoundTextElementId(element);
|
|
||||||
|
|
||||||
const boundsCurrentWidth = esx2 - esx1;
|
const boundsCurrentWidth = esx2 - esx1;
|
||||||
const boundsCurrentHeight = esy2 - esy1;
|
const boundsCurrentHeight = esy2 - esy1;
|
||||||
|
|
||||||
@ -453,6 +452,9 @@ export const resizeSingleElement = (
|
|||||||
if (transformHandleDirection.includes("n")) {
|
if (transformHandleDirection.includes("n")) {
|
||||||
scaleY = (startBottomRight[1] - rotatedPointer[1]) / boundsCurrentHeight;
|
scaleY = (startBottomRight[1] - rotatedPointer[1]) / boundsCurrentHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const boundTextElement = getBoundTextElement(element);
|
||||||
|
|
||||||
// Linear elements dimensions differ from bounds dimensions
|
// Linear elements dimensions differ from bounds dimensions
|
||||||
const eleInitialWidth = stateAtResizeStart.width;
|
const eleInitialWidth = stateAtResizeStart.width;
|
||||||
const eleInitialHeight = stateAtResizeStart.height;
|
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] =
|
const [newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2] =
|
||||||
getResizedElementAbsoluteCoords(
|
getResizedElementAbsoluteCoords(
|
||||||
stateAtResizeStart,
|
stateAtResizeStart,
|
||||||
@ -491,11 +500,6 @@ export const resizeSingleElement = (
|
|||||||
const newBoundsWidth = newBoundsX2 - newBoundsX1;
|
const newBoundsWidth = newBoundsX2 - newBoundsX1;
|
||||||
const newBoundsHeight = newBoundsY2 - newBoundsY1;
|
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
|
// Calculate new topLeft based on fixed corner during resize
|
||||||
let newTopLeft = [...startTopLeft] as [number, number];
|
let newTopLeft = [...startTopLeft] as [number, number];
|
||||||
if (["n", "w", "nw"].includes(transformHandleDirection)) {
|
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 (
|
if (
|
||||||
resizedElement.width >= minWidth &&
|
resizedElement.width !== 0 &&
|
||||||
resizedElement.height !== 0 &&
|
resizedElement.height !== 0 &&
|
||||||
Number.isFinite(resizedElement.x) &&
|
Number.isFinite(resizedElement.x) &&
|
||||||
Number.isFinite(resizedElement.y)
|
Number.isFinite(resizedElement.y)
|
||||||
|
@ -144,6 +144,7 @@ export const handleBindTextResize = (
|
|||||||
}
|
}
|
||||||
|
|
||||||
const updatedY = element.y + containerHeight / 2 - nextHeight / 2;
|
const updatedY = element.y + containerHeight / 2 - nextHeight / 2;
|
||||||
|
|
||||||
mutateElement(textElement, {
|
mutateElement(textElement, {
|
||||||
text,
|
text,
|
||||||
// preserve padding and set width correctly
|
// preserve padding and set width correctly
|
||||||
@ -355,6 +356,7 @@ export const charWidth = (() => {
|
|||||||
const width = getTextWidth(char, font);
|
const width = getTextWidth(char, font);
|
||||||
cachedCharWidth[font][ascii] = width;
|
cachedCharWidth[font][ascii] = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedCharWidth[font][ascii];
|
return cachedCharWidth[font][ascii];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -367,14 +369,14 @@ export const charWidth = (() => {
|
|||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
export const getApproxMinLineWidth = (font: FontString) => {
|
export const getApproxMinLineWidth = (font: FontString) => {
|
||||||
const minCharWidth = getMinCharWidth(font);
|
const maxCharWidth = getMaxCharWidth(font);
|
||||||
if (minCharWidth === 0) {
|
if (maxCharWidth === 0) {
|
||||||
return (
|
return (
|
||||||
measureText(DUMMY_TEXT.split("").join("\n"), font).width +
|
measureText(DUMMY_TEXT.split("").join("\n"), font).width +
|
||||||
BOUND_TEXT_PADDING * 2
|
BOUND_TEXT_PADDING * 2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return minCharWidth + BOUND_TEXT_PADDING * 2;
|
return maxCharWidth + BOUND_TEXT_PADDING * 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getApproxMinLineHeight = (font: FontString) => {
|
export const getApproxMinLineHeight = (font: FontString) => {
|
||||||
@ -391,6 +393,15 @@ export const getMinCharWidth = (font: FontString) => {
|
|||||||
return Math.min(...cacheWithOutEmpty);
|
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) => {
|
export const getApproxCharsToFitInWidth = (font: FontString, width: number) => {
|
||||||
// Generally lower case is used so converting to lower case
|
// Generally lower case is used so converting to lower case
|
||||||
const dummyText = DUMMY_TEXT.toLocaleLowerCase();
|
const dummyText = DUMMY_TEXT.toLocaleLowerCase();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user