From a4a95a591ab5b1c767eb995c2cb1e5ee9224b22c Mon Sep 17 00:00:00 2001 From: ad1992 Date: Mon, 28 Mar 2022 15:03:29 +0530 Subject: [PATCH] Add stackedOnTop to make sure the custom element is always rendered on top of all when stackedOnTop is true --- src/components/App.tsx | 2 +- src/constants.ts | 1 + src/packages/excalidraw/example/App.js | 1 + src/scene/Scene.ts | 26 +++++++++++++++++++++++++- src/types.ts | 1 + 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/components/App.tsx b/src/components/App.tsx index e52dea1e4..5b3fce84d 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -398,7 +398,7 @@ class App extends React.Component { id: this.id, }; - this.scene = new Scene(); + this.scene = new Scene(this); this.library = new Library(this); this.history = new History(); this.actionManager = new ActionManager( diff --git a/src/constants.ts b/src/constants.ts index 5bf8c3bb1..d8e3bffb0 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -159,6 +159,7 @@ export const DEFAULT_CUSTOM_ELEMENT_CONFIG: Required = { svg: "", width: 40, height: 40, + stackedOnTop: false, }; export const MQ_MAX_WIDTH_PORTRAIT = 730; export const MQ_MAX_WIDTH_LANDSCAPE = 1000; diff --git a/src/packages/excalidraw/example/App.js b/src/packages/excalidraw/example/App.js index f9e21f5dd..55e09e6eb 100644 --- a/src/packages/excalidraw/example/App.js +++ b/src/packages/excalidraw/example/App.js @@ -202,6 +202,7 @@ export default function App() { `)}`, transformHandles: false, + stackedOnTop: true, }, ]; }; diff --git a/src/scene/Scene.ts b/src/scene/Scene.ts index 5d981c3f3..ea239751b 100644 --- a/src/scene/Scene.ts +++ b/src/scene/Scene.ts @@ -5,6 +5,9 @@ import { } from "../element/types"; import { getNonDeletedElements, isNonDeletedElement } from "../element"; import { LinearElementEditor } from "../element/linearElementEditor"; +import App from "../components/App"; +import { isCustomElement } from "../element/typeChecks"; +import { getCustomElementConfig } from "../utils"; type ElementIdKey = InstanceType["elementId"]; type ElementKey = ExcalidrawElement | ElementIdKey; @@ -26,7 +29,11 @@ class Scene { private static sceneMapByElement = new WeakMap(); private static sceneMapById = new Map(); + private app: App; + constructor(app: App) { + this.app = app; + } static mapElementToScene(elementKey: ElementKey, scene: Scene) { if (isIdKey(elementKey)) { this.sceneMapById.set(elementKey, scene); @@ -91,12 +98,29 @@ class Scene { } replaceAllElements(nextElements: readonly ExcalidrawElement[]) { - this.elements = nextElements; + this.elements = []; + const elements: ExcalidrawElement[] = []; this.elementsMap.clear(); + const elementsToBeStackedOnTop: ExcalidrawElement[] = []; nextElements.forEach((element) => { + if (isCustomElement(element)) { + const config = getCustomElementConfig( + this.app.props.customElementsConfig, + element.customType, + ); + if (config?.stackedOnTop) { + elementsToBeStackedOnTop.push(element); + } else { + elements.push(element); + } + } else { + elements.push(element); + } this.elementsMap.set(element.id, element); Scene.mapElementToScene(element, this); }); + elementsToBeStackedOnTop.forEach((ele) => elements.push(ele)); + this.elements = elements; this.nonDeletedElements = getNonDeletedElements(this.elements); this.informMutation(); } diff --git a/src/types.ts b/src/types.ts index 48bda7ae9..2fad70822 100644 --- a/src/types.ts +++ b/src/types.ts @@ -215,6 +215,7 @@ export type CustomElementConfig = { svg: string; width?: number; height?: number; + stackedOnTop: boolean; }; export interface ExcalidrawProps { onChange?: (