瀏覽代碼

reduce safari LS

Aakansha Doshi 2 年之前
父節點
當前提交
6001f59d38
共有 2 個文件被更改,包括 54 次插入3 次删除
  1. 38 1
      src/element/textElement.ts
  2. 16 2
      src/element/textWysiwyg.tsx

+ 38 - 1
src/element/textElement.ts

@@ -347,6 +347,41 @@ export const measureBaseline = (
   return baseline;
 };
 
+export const measureDOMHeight = (
+  text: string,
+  font: FontString,
+  lineHeight: ExcalidrawTextElement["lineHeight"],
+  wrapInContainer?: boolean,
+) => {
+  const container = document.createElement("div");
+  container.style.position = "absolute";
+  container.style.whiteSpace = "pre";
+  container.style.font = font;
+  container.style.minHeight = "1em";
+  if (wrapInContainer) {
+    container.style.overflow = "hidden";
+    container.style.wordBreak = "break-word";
+    container.style.whiteSpace = "pre-wrap";
+  }
+
+  container.style.lineHeight = String(lineHeight);
+
+  container.innerText = text;
+
+  // Baseline is important for positioning text on canvas
+  document.body.appendChild(container);
+
+  const span = document.createElement("span");
+  span.style.display = "inline-block";
+  span.style.overflow = "hidden";
+  span.style.width = "1px";
+  span.style.height = "1px";
+  container.appendChild(span);
+  const domHeight = container.offsetHeight;
+
+  document.body.removeChild(container);
+  return domHeight;
+};
 /**
  * To get unitless line-height (if unknown) we can calculate it by dividing
  * height-per-line by fontSize.
@@ -366,7 +401,9 @@ export const getLineHeightInPx = (
   fontSize: ExcalidrawTextElement["fontSize"],
   lineHeight: ExcalidrawTextElement["lineHeight"],
 ) => {
-  return fontSize * lineHeight;
+  const res = fontSize * lineHeight;
+
+  return res;
 };
 
 // FIXME rename to getApproxMinContainerHeight

+ 16 - 2
src/element/textWysiwyg.tsx

@@ -11,7 +11,7 @@ import {
   isBoundToContainer,
   isTextElement,
 } from "./typeChecks";
-import { CLASSES, VERTICAL_ALIGN } from "../constants";
+import { CLASSES, isSafari, VERTICAL_ALIGN } from "../constants";
 import {
   ExcalidrawElement,
   ExcalidrawLinearElement,
@@ -35,6 +35,8 @@ import {
   getMaxContainerHeight,
   getMaxContainerWidth,
   computeContainerDimensionForBoundText,
+  measureDOMHeight,
+  splitIntoLines,
 } from "./textElement";
 import {
   actionDecreaseFontSize,
@@ -271,13 +273,25 @@ export const textWysiwyg = ({
       } else {
         textElementWidth += 0.5;
       }
+      const domHeight = measureDOMHeight(
+        updatedTextElement.text,
+        getFontString(updatedTextElement),
+        updatedTextElement.lineHeight,
+      );
+
+      let lineHeight = element.lineHeight;
+      if (isSafari && domHeight > textElementHeight) {
+        lineHeight = (Math.floor(element.lineHeight * element.fontSize) /
+          element.fontSize) as ExcalidrawTextElement["lineHeight"];
+      }
+
       // 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 ¯\_(ツ)_/¯
-        lineHeight: element.lineHeight,
+        lineHeight,
         width: `${textElementWidth}px`,
         height: `${textElementHeight}px`,
         left: `${viewportX}px`,