Browse Source

fix: always make sure we render bound text above containers (#7880)

David Luzar 1 year ago
parent
commit
f59b4f6af4

+ 29 - 3
packages/excalidraw/renderer/staticScene.ts

@@ -9,6 +9,7 @@ import {
 import {
 import {
   isEmbeddableElement,
   isEmbeddableElement,
   isIframeLikeElement,
   isIframeLikeElement,
+  isTextElement,
 } from "../element/typeChecks";
 } from "../element/typeChecks";
 import { renderElement } from "../renderer/renderElement";
 import { renderElement } from "../renderer/renderElement";
 import { createPlaceholderEmbeddableLabel } from "../element/embeddable";
 import { createPlaceholderEmbeddableLabel } from "../element/embeddable";
@@ -28,6 +29,7 @@ import {
 } from "../components/hyperlink/helpers";
 } from "../components/hyperlink/helpers";
 import { bootstrapCanvas, getNormalizedCanvasDimensions } from "./helpers";
 import { bootstrapCanvas, getNormalizedCanvasDimensions } from "./helpers";
 import { throttleRAF } from "../utils";
 import { throttleRAF } from "../utils";
+import { getBoundTextElement } from "../element/textElement";
 
 
 const strokeGrid = (
 const strokeGrid = (
   context: CanvasRenderingContext2D,
   context: CanvasRenderingContext2D,
@@ -236,13 +238,22 @@ const _renderStaticScene = ({
       try {
       try {
         const frameId = element.frameId || appState.frameToHighlight?.id;
         const frameId = element.frameId || appState.frameToHighlight?.id;
 
 
+        if (
+          isTextElement(element) &&
+          element.containerId &&
+          elementsMap.has(element.containerId)
+        ) {
+          // will be rendered with the container
+          return;
+        }
+
+        context.save();
+
         if (
         if (
           frameId &&
           frameId &&
           appState.frameRendering.enabled &&
           appState.frameRendering.enabled &&
           appState.frameRendering.clip
           appState.frameRendering.clip
         ) {
         ) {
-          context.save();
-
           const frame = getTargetFrame(element, elementsMap, appState);
           const frame = getTargetFrame(element, elementsMap, appState);
 
 
           // TODO do we need to check isElementInFrame here?
           // TODO do we need to check isElementInFrame here?
@@ -258,7 +269,6 @@ const _renderStaticScene = ({
             renderConfig,
             renderConfig,
             appState,
             appState,
           );
           );
-          context.restore();
         } else {
         } else {
           renderElement(
           renderElement(
             element,
             element,
@@ -270,6 +280,22 @@ const _renderStaticScene = ({
             appState,
             appState,
           );
           );
         }
         }
+
+        const boundTextElement = getBoundTextElement(element, allElementsMap);
+        if (boundTextElement) {
+          renderElement(
+            boundTextElement,
+            elementsMap,
+            allElementsMap,
+            rc,
+            context,
+            renderConfig,
+            appState,
+          );
+        }
+
+        context.restore();
+
         if (!isExporting) {
         if (!isExporting) {
           renderLinkIcon(element, context, appState, elementsMap);
           renderLinkIcon(element, context, appState, elementsMap);
         }
         }

+ 23 - 0
packages/excalidraw/renderer/staticSvgScene.ts

@@ -618,6 +618,15 @@ export const renderSceneToSvg = (
     .filter((el) => !isIframeLikeElement(el))
     .filter((el) => !isIframeLikeElement(el))
     .forEach((element) => {
     .forEach((element) => {
       if (!element.isDeleted) {
       if (!element.isDeleted) {
+        if (
+          isTextElement(element) &&
+          element.containerId &&
+          elementsMap.has(element.containerId)
+        ) {
+          // will be rendered with the container
+          return;
+        }
+
         try {
         try {
           renderElementToSvg(
           renderElementToSvg(
             element,
             element,
@@ -629,6 +638,20 @@ export const renderSceneToSvg = (
             element.y + renderConfig.offsetY,
             element.y + renderConfig.offsetY,
             renderConfig,
             renderConfig,
           );
           );
+
+          const boundTextElement = getBoundTextElement(element, elementsMap);
+          if (boundTextElement) {
+            renderElementToSvg(
+              boundTextElement,
+              elementsMap,
+              rsvg,
+              svgRoot,
+              files,
+              boundTextElement.x + renderConfig.offsetX,
+              boundTextElement.y + renderConfig.offsetY,
+              renderConfig,
+            );
+          }
         } catch (error: any) {
         } catch (error: any) {
           console.error(error);
           console.error(error);
         }
         }