diff --git a/src/element/textElement.ts b/src/element/textElement.ts index efe799a90..1de918ce0 100644 --- a/src/element/textElement.ts +++ b/src/element/textElement.ts @@ -205,8 +205,14 @@ export const measureText = ( }; const DUMMY_TEXT = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toLocaleUpperCase(); +const cacheApproxLineHeight: { [key: FontString]: number } = {}; + export const getApproxLineHeight = (font: FontString) => { - return measureText(DUMMY_TEXT, font, null).height; + if (cacheApproxLineHeight[font]) { + return cacheApproxLineHeight[font]; + } + cacheApproxLineHeight[font] = measureText(DUMMY_TEXT, font, null).height; + return cacheApproxLineHeight[font]; }; let canvas: HTMLCanvasElement | undefined; diff --git a/src/element/textWysiwyg.tsx b/src/element/textWysiwyg.tsx index 7b8628741..b82513f6e 100644 --- a/src/element/textWysiwyg.tsx +++ b/src/element/textWysiwyg.tsx @@ -102,10 +102,12 @@ export const textWysiwyg = ({ return false; }; let originalContainerHeight: number; - let approxLineHeight = getApproxLineHeight(getFontString(element)); const updateWysiwygStyle = () => { - const updatedElement = Scene.getScene(element)?.getElement(id); + const updatedElement = Scene.getScene(element)?.getElement( + id, + ) as ExcalidrawTextElement; + const approxLineHeight = getApproxLineHeight(getFontString(updatedElement)); if (updatedElement && isTextElement(updatedElement)) { let coordX = updatedElement.x; let coordY = updatedElement.y; @@ -128,8 +130,6 @@ export const textWysiwyg = ({ height = editorHeight; } if (propertiesUpdated) { - approxLineHeight = getApproxLineHeight(getFontString(updatedElement)); - originalContainerHeight = container.height; // update height of the editor after properties updated @@ -268,10 +268,14 @@ export const textWysiwyg = ({ if (onChange) { editable.oninput = () => { + const updatedElement = Scene.getScene(element)?.getElement( + id, + ) as ExcalidrawTextElement; + const font = getFontString(updatedElement); // using scrollHeight here since we need to calculate // number of lines so cannot use editable.style.height // as that gets updated below - const lines = editable.scrollHeight / approxLineHeight; + const lines = editable.scrollHeight / getApproxLineHeight(font); // auto increase height only when lines > 1 so its // measured correctly and vertically alignes for // first line as well as setting height to "auto" @@ -283,7 +287,7 @@ export const textWysiwyg = ({ const container = getContainerElement(element); const actualLineCount = wrapText( editable.value, - getFontString(element), + font, container!.width, ).split("\n").length;