From e41ea9562b1142dafd99509c7be90f9370e4c925 Mon Sep 17 00:00:00 2001 From: Aakansha Doshi Date: Sat, 28 Jan 2023 16:39:53 +0530 Subject: [PATCH] fix: set the width correctly using measureText in editor (#6162) --- src/element/textElement.test.ts | 2 +- src/element/textElement.ts | 16 +++++++--------- src/element/textWysiwyg.tsx | 16 ++++++++++++---- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/element/textElement.test.ts b/src/element/textElement.test.ts index b849db01..e1b9ff6f 100644 --- a/src/element/textElement.test.ts +++ b/src/element/textElement.test.ts @@ -171,7 +171,7 @@ describe("Test measureText", () => { expect(res.container).toMatchInlineSnapshot(`
maxWidth) { - width = width - 1; - } + const width = container.offsetWidth; const height = container.offsetHeight; document.body.removeChild(container); if (isTestEnv()) { @@ -332,8 +327,11 @@ const getLineWidth = (text: string, font: FontString) => { if (isTestEnv()) { return metrics.width * 10; } + // Since measureText behaves differently in different browsers + // OS so considering a adjustment factor of 0.2 + const adjustmentFactor = 0.2; - return metrics.width; + return metrics.width + adjustmentFactor; }; export const getTextWidth = (text: string, font: FontString) => { diff --git a/src/element/textWysiwyg.tsx b/src/element/textWysiwyg.tsx index d525221a..7b0098ce 100644 --- a/src/element/textWysiwyg.tsx +++ b/src/element/textWysiwyg.tsx @@ -142,11 +142,11 @@ export const textWysiwyg = ({ const appState = app.state; const updatedTextElement = Scene.getScene(element)?.getElement(id); + if (!updatedTextElement) { return; } const { textAlign, verticalAlign } = updatedTextElement; - const approxLineHeight = getApproxLineHeight( getFontString(updatedTextElement), ); @@ -161,6 +161,7 @@ export const textWysiwyg = ({ // Set to element height by default since that's // what is going to be used for unbounded text let textElementHeight = updatedTextElement.height; + if (container && updatedTextElement.containerId) { if (isArrowElement(container)) { const boundTextCoords = @@ -206,7 +207,6 @@ export const textWysiwyg = ({ maxHeight = getMaxContainerHeight(container); // autogrow container height if text exceeds - if (!isArrowElement(container) && textElementHeight > maxHeight) { const diff = Math.min( textElementHeight - maxHeight, @@ -276,7 +276,6 @@ export const textWysiwyg = ({ // Make sure text editor height doesn't go beyond viewport const editorMaxHeight = (appState.height - viewportY) / appState.zoom.value; - Object.assign(editable.style, { font: getFontString(updatedTextElement), // must be defined *after* font ¯\_(ツ)_/¯ @@ -395,11 +394,12 @@ export const textWysiwyg = ({ // first line as well as setting height to "auto" // doubles the height as soon as user starts typing if (isBoundToContainer(element) && lines > 1) { + const container = getContainerElement(element); + let height = "auto"; editable.style.height = "0px"; let heightSet = false; if (lines === 2) { - const container = getContainerElement(element); const actualLineCount = wrapText( editable.value, font, @@ -416,6 +416,14 @@ export const textWysiwyg = ({ heightSet = true; } } + const wrappedText = wrapText( + normalizeText(editable.value), + font, + getMaxContainerWidth(container!), + ); + const width = getTextWidth(wrappedText, font); + editable.style.width = `${width}px`; + if (!heightSet) { editable.style.height = `${editable.scrollHeight}px`; }