瀏覽代碼

feat: Scale font size when bound text containers resized with shift pressed (#4828)

* feat: Scale font size when bound text containers resized with shift pressed

* revert fontsize once shift pressed/released after resize

* make slightly more typesafe

Co-authored-by: dwelle <luzar.david@gmail.com>
Aakansha Doshi 3 年之前
父節點
當前提交
1acfaf6b6e
共有 2 個文件被更改,包括 38 次插入9 次删除
  1. 1 1
      src/actions/actionFlip.ts
  2. 37 8
      src/element/resizeElements.ts

+ 1 - 1
src/actions/actionFlip.ts

@@ -155,7 +155,7 @@ const flipElement = (
     // calculate new x-coord for transformation
     newNCoordsX = usingNWHandle ? element.x + 2 * width : element.x - 2 * width;
     resizeSingleElement(
-      element,
+      new Map().set(element.id, element),
       true,
       element,
       usingNWHandle ? "nw" : "ne",

+ 37 - 8
src/element/resizeElements.ts

@@ -106,7 +106,7 @@ export const transformElements = (
       updateBoundElements(element);
     } else if (transformHandleType) {
       resizeSingleElement(
-        pointerDownState.originalElements.get(element.id) as typeof element,
+        pointerDownState.originalElements,
         shouldMaintainAspectRatio,
         element,
         transformHandleType,
@@ -397,7 +397,7 @@ const resizeSingleTextElement = (
 };
 
 export const resizeSingleElement = (
-  stateAtResizeStart: NonDeletedExcalidrawElement,
+  originalElements: PointerDownState["originalElements"],
   shouldMaintainAspectRatio: boolean,
   element: NonDeletedExcalidrawElement,
   transformHandleDirection: TransformHandleDirection,
@@ -405,6 +405,7 @@ export const resizeSingleElement = (
   pointerX: number,
   pointerY: number,
 ) => {
+  const stateAtResizeStart = originalElements.get(element.id)!;
   // Gets bounds corners
   const [x1, y1, x2, y2] = getResizedElementAbsoluteCoords(
     stateAtResizeStart,
@@ -439,6 +440,9 @@ export const resizeSingleElement = (
   let scaleX = atStartBoundsWidth / boundsCurrentWidth;
   let scaleY = atStartBoundsHeight / boundsCurrentHeight;
 
+  let boundTextFont: { fontSize?: number; baseline?: number } = {};
+  const boundTextElement = getBoundTextElement(element);
+
   if (transformHandleDirection.includes("e")) {
     scaleX = (rotatedPointer[0] - startTopLeft[0]) / boundsCurrentWidth;
   }
@@ -452,8 +456,6 @@ export const resizeSingleElement = (
     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;
@@ -484,10 +486,34 @@ 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 stateOfBoundTextElementAtResize = originalElements.get(
+      boundTextElement.id,
+    ) as typeof boundTextElement | undefined;
+    if (stateOfBoundTextElementAtResize) {
+      boundTextFont = {
+        fontSize: stateOfBoundTextElementAtResize.fontSize,
+        baseline: stateOfBoundTextElementAtResize.baseline,
+      };
+    }
+    if (shouldMaintainAspectRatio) {
+      const nextFont = measureFontSizeFromWH(
+        boundTextElement,
+        eleNewWidth - BOUND_TEXT_PADDING * 2,
+        eleNewHeight - BOUND_TEXT_PADDING * 2,
+      );
+      if (nextFont === null) {
+        return;
+      }
+      boundTextFont = {
+        fontSize: nextFont.size,
+        baseline: nextFont.baseline,
+      };
+    } else {
+      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] =
@@ -602,6 +628,9 @@ export const resizeSingleElement = (
       newSize: { width: resizedElement.width, height: resizedElement.height },
     });
     mutateElement(element, resizedElement);
+    if (boundTextElement && boundTextFont) {
+      mutateElement(boundTextElement, { fontSize: boundTextFont.fontSize });
+    }
     handleBindTextResize(element, transformHandleDirection);
   }
 };