Explorar o código

perf: cache approx line height in textwysiwg (#4651)

Aakansha Doshi %!s(int64=3) %!d(string=hai) anos
pai
achega
abff780983
Modificáronse 2 ficheiros con 17 adicións e 7 borrados
  1. 7 1
      src/element/textElement.ts
  2. 10 6
      src/element/textWysiwyg.tsx

+ 7 - 1
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;

+ 10 - 6
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;