Browse Source

fix: refresh wysiwyg position on canvas resize (#3008)

David Luzar 4 years ago
parent
commit
4b253c7362
4 changed files with 27 additions and 3 deletions
  1. 6 0
      package-lock.json
  2. 1 0
      package.json
  3. 1 0
      src/components/App.tsx
  4. 19 3
      src/element/textWysiwyg.tsx

+ 6 - 0
package-lock.json

@@ -3356,6 +3356,12 @@
         "@types/react": "*"
       }
     },
+    "@types/resize-observer-browser": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz",
+      "integrity": "sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ==",
+      "dev": true
+    },
     "@types/resolve": {
       "version": "0.0.8",
       "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",

+ 1 - 0
package.json

@@ -51,6 +51,7 @@
   "devDependencies": {
     "@types/lodash.throttle": "4.1.6",
     "@types/pako": "1.0.1",
+    "@types/resize-observer-browser": "0.1.5",
     "eslint-config-prettier": "7.2.0",
     "eslint-plugin-prettier": "3.3.1",
     "firebase-tools": "9.3.0",

+ 1 - 0
src/components/App.tsx

@@ -1551,6 +1551,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
     textWysiwyg({
       id: element.id,
       appState: this.state,
+      canvas: this.canvas,
       getViewportCoords: (x, y) => {
         const { x: viewportX, y: viewportY } = sceneCoordsToViewportCoords(
           {

+ 19 - 3
src/element/textWysiwyg.tsx

@@ -38,6 +38,7 @@ export const textWysiwyg = ({
   onSubmit,
   getViewportCoords,
   element,
+  canvas,
 }: {
   id: ExcalidrawElement["id"];
   appState: AppState;
@@ -45,6 +46,7 @@ export const textWysiwyg = ({
   onSubmit: (text: string) => void;
   getViewportCoords: (x: number, y: number) => [number, number];
   element: ExcalidrawElement;
+  canvas: HTMLCanvasElement | null;
 }) => {
   const updateWysiwygStyle = () => {
     const updatedElement = Scene.getScene(element)?.getElement(id);
@@ -151,6 +153,10 @@ export const textWysiwyg = ({
     editable.oninput = null;
     editable.onkeydown = null;
 
+    if (observer) {
+      observer.disconnect();
+    }
+
     window.removeEventListener("resize", updateWysiwygStyle);
     window.removeEventListener("wheel", stopEvent, true);
     window.removeEventListener("pointerdown", onPointerDown);
@@ -197,9 +203,19 @@ export const textWysiwyg = ({
   let isDestroyed = false;
 
   editable.onblur = handleSubmit;
-  // reposition wysiwyg in case of window resize. Happens on mobile when
-  // device keyboard is opened.
-  window.addEventListener("resize", updateWysiwygStyle);
+
+  // reposition wysiwyg in case of canvas is resized. Using ResizeObserver
+  // is preferred so we catch changes from host, where window may not resize.
+  let observer: ResizeObserver | null = null;
+  if (canvas && "ResizeObserver" in window) {
+    observer = new window.ResizeObserver(() => {
+      updateWysiwygStyle();
+    });
+    observer.observe(canvas);
+  } else {
+    window.addEventListener("resize", updateWysiwygStyle);
+  }
+
   window.addEventListener("pointerdown", onPointerDown);
   window.addEventListener("wheel", stopEvent, {
     passive: false,