diff --git a/src/element/resizeElements.ts b/src/element/resizeElements.ts index ff7956f38..8ab611069 100644 --- a/src/element/resizeElements.ts +++ b/src/element/resizeElements.ts @@ -20,6 +20,7 @@ import { getCommonBoundingBox, } from "./bounds"; import { + isBoundToContainer, isFreeDrawElement, isLinearElement, isTextElement, @@ -39,9 +40,11 @@ import { getApproxMinLineWidth, getBoundTextElement, getBoundTextElementId, + getContainerElement, handleBindTextResize, measureText, } from "./textElement"; +import { getMaxContainerWidth } from "./newElement"; export const normalizeAngle = (angle: number): number => { if (angle >= 2 * Math.PI) { @@ -182,14 +185,21 @@ const measureFontSizeFromWH = ( nextHeight: number, ): { size: number; baseline: number } | null => { // We only use width to scale font on resize - const nextFontSize = element.fontSize * (nextWidth / element.width); + let width = element.width; + + const hasContainer = isBoundToContainer(element); + if (hasContainer) { + const container = getContainerElement(element)!; + width = getMaxContainerWidth(container); + } + const nextFontSize = element.fontSize * (nextWidth / width); if (nextFontSize < MIN_FONT_SIZE) { return null; } const metrics = measureText( element.text, getFontString({ fontSize: nextFontSize, fontFamily: element.fontFamily }), - element.containerId ? element.width : null, + hasContainer ? width : null, ); return { size: nextFontSize, diff --git a/src/element/textWysiwyg.test.tsx b/src/element/textWysiwyg.test.tsx index c900ba62f..6456781d5 100644 --- a/src/element/textWysiwyg.test.tsx +++ b/src/element/textWysiwyg.test.tsx @@ -1099,5 +1099,27 @@ describe("textWysiwyg", () => { { id: text.id, type: "text" }, ]); }); + + it("should scale font size correctly when resizing using shift", async () => { + Keyboard.keyPress(KEYS.ENTER); + + const editor = document.querySelector( + ".excalidraw-textEditorContainer > textarea", + ) as HTMLTextAreaElement; + await new Promise((r) => setTimeout(r, 0)); + fireEvent.change(editor, { target: { value: "Hello" } }); + editor.blur(); + const textElement = h.elements[1] as ExcalidrawTextElement; + expect(rectangle.width).toBe(90); + expect(rectangle.height).toBe(75); + expect(textElement.fontSize).toBe(20); + + resize(rectangle, "ne", [rectangle.x + 100, rectangle.y - 50], { + shift: true, + }); + expect(rectangle.width).toBe(200); + expect(rectangle.height).toBe(166.66666666666669); + expect(textElement.fontSize).toBe(47.5); + }); }); }); diff --git a/src/element/typeChecks.ts b/src/element/typeChecks.ts index fdebca875..053b31ccb 100644 --- a/src/element/typeChecks.ts +++ b/src/element/typeChecks.ts @@ -139,6 +139,9 @@ export const isBoundToContainer = ( element: ExcalidrawElement | null, ): element is ExcalidrawTextElementWithContainer => { return ( - element !== null && isTextElement(element) && element.containerId !== null + element !== null && + "containerId" in element && + element.containerId !== null && + isTextElement(element) ); };