소스 검색

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
Aakansha Doshi 3 년 전
부모
커밋
4604c8d823
2개의 변경된 파일27개의 추가작업 그리고 16개의 파일을 삭제
  1. 13 13
      src/element/resizeElements.ts
  2. 14 3
      src/element/textElement.ts

+ 13 - 13
src/element/resizeElements.ts

@@ -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)

+ 14 - 3
src/element/textElement.ts

@@ -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();