From 5e6764667264c9ee9b7bc79370bffadd2c533584 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kav=C3=ADk?= Date: Thu, 10 Oct 2024 23:58:14 +0200 Subject: [PATCH] draw_diagram_element --- .../src/diagram_panel/excalidraw_canvas.rs | 3 + frontend/src/script_bridge.rs | 13 +++ .../typescript/bundles/excalidraw_canvas.js | 12 ++- .../excalidraw_canvas/excalidraw_canvas.tsx | 82 +++++++++++-------- .../excalidraw_canvas/package-lock.json | 16 ++-- .../typescript/excalidraw_canvas/package.json | 4 +- 6 files changed, 86 insertions(+), 44 deletions(-) diff --git a/frontend/src/diagram_panel/excalidraw_canvas.rs b/frontend/src/diagram_panel/excalidraw_canvas.rs index 5414164..888c39e 100644 --- a/frontend/src/diagram_panel/excalidraw_canvas.rs +++ b/frontend/src/diagram_panel/excalidraw_canvas.rs @@ -73,5 +73,8 @@ mod js_bridge { #[wasm_bindgen(method)] pub async fn init(this: &ExcalidrawController, parent_element: &JsValue); + + #[wasm_bindgen(method)] + pub fn draw_diagram_element(this: &ExcalidrawController, excalidraw_element: JsValue); } } diff --git a/frontend/src/script_bridge.rs b/frontend/src/script_bridge.rs index 183fad1..f29217f 100644 --- a/frontend/src/script_bridge.rs +++ b/frontend/src/script_bridge.rs @@ -78,4 +78,17 @@ impl FW { pub async fn remove_all_decoders() -> RemovedDecodersCount { platform::remove_all_decoders().await } + + // @TODO replace argument once Excalidraw's `convertToExcalidrawElements` works: {type: "rectangle", x: 100, y: 250} + /// JS: `FW.draw_diagram_element({id: 'my_rectangle', type: 'rectangle', x: 500, y: 250, strokeColor: 'black', backgroundColor: 'lightblue', fillStyle: 'solid', strokeWidth: 5, strokeStyle: 'solid', roundness: null, roughness: 0, opacity: 100, width: 100, height: 50, angle: 0, seed: 0, version: 0, versionNonce: 0, isDeleted: false, groupIds: [], frameId: null, boundElements: null, updated: 0, link: null, locked: false, customData: {}})` + pub async fn draw_diagram_element(excalidraw_element: JsValue) { + if let Some(controller) = STORE + .excalidraw_canvas_controller + .lock_ref() + .lock_ref() + .as_ref() + { + controller.draw_diagram_element(excalidraw_element) + } + } } diff --git a/frontend/typescript/bundles/excalidraw_canvas.js b/frontend/typescript/bundles/excalidraw_canvas.js index 00365af..b7e6243 100644 --- a/frontend/typescript/bundles/excalidraw_canvas.js +++ b/frontend/typescript/bundles/excalidraw_canvas.js @@ -74738,8 +74738,17 @@ var import_excalidraw = __toESM(require_main()); var React = __toESM(require_react()); var ReactDOM = __toESM(require_client()); var ExcalidrawController = class { + api; constructor() { } + draw_diagram_element(excalidraw_element) { + if (typeof this.api !== "undefined") { + const elements = this.api.getSceneElements(); + this.api.updateScene({ + elements: elements.concat(excalidraw_element) + }); + } + } async init(parent_element) { const App = () => { return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { style: { height: "100%" } }, /* @__PURE__ */ React.createElement( @@ -74755,7 +74764,8 @@ var ExcalidrawController = class { currentItemRoughness: 0, // Font family: Code currentItemFontFamily: 3 - } } + } }, + excalidrawAPI: (api) => this.api = api }, /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu, null, /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu.DefaultItems.LoadScene, null), /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu.DefaultItems.SaveToActiveFile, null), /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu.DefaultItems.Export, null), /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu.DefaultItems.SaveAsImage, null), /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu.DefaultItems.ClearCanvas, null), /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu.DefaultItems.ToggleTheme, null), /* @__PURE__ */ React.createElement(import_excalidraw.MainMenu.DefaultItems.ChangeCanvasBackground, null)) ))); diff --git a/frontend/typescript/excalidraw_canvas/excalidraw_canvas.tsx b/frontend/typescript/excalidraw_canvas/excalidraw_canvas.tsx index 3c2ec5f..ffd0cd4 100644 --- a/frontend/typescript/excalidraw_canvas/excalidraw_canvas.tsx +++ b/frontend/typescript/excalidraw_canvas/excalidraw_canvas.tsx @@ -1,44 +1,60 @@ import { Excalidraw, MainMenu } from '@excalidraw/excalidraw' +import { ExcalidrawImperativeAPI } from '@excalidraw/excalidraw/types/types' +import { ExcalidrawElement } from '@excalidraw/excalidraw/types/element/types' +// @TODO doesn't work with Excalidraw 0.17.6 +// import { ExcalidrawElementSkeleton, convertToExcalidrawElements } from '@excalidraw/excalidraw/types/data/transform' import * as React from 'react' import * as ReactDOM from 'react-dom/client' export class ExcalidrawController { + api: ExcalidrawImperativeAPI | undefined + constructor() {} + draw_diagram_element(excalidraw_element: ExcalidrawElement) { + if (typeof this.api !== 'undefined') { + const elements = this.api.getSceneElements() + this.api.updateScene({ + elements: elements.concat(excalidraw_element) + }) + } + } + async init(parent_element: HTMLElement) { - const App = () => { - return ( - <> -
- - - - - - - - - - - -
- - ); - }; - const root = ReactDOM.createRoot(parent_element); - root.render(React.createElement(App)); + const App = () => { + return ( + <> +
+ this.api = api} + > + + + + + + + + + + +
+ + ); + }; + const root = ReactDOM.createRoot(parent_element); + root.render(React.createElement(App)); } } \ No newline at end of file diff --git a/frontend/typescript/excalidraw_canvas/package-lock.json b/frontend/typescript/excalidraw_canvas/package-lock.json index fa7e516..dfafe65 100644 --- a/frontend/typescript/excalidraw_canvas/package-lock.json +++ b/frontend/typescript/excalidraw_canvas/package-lock.json @@ -7,7 +7,7 @@ "dependencies": { "@excalidraw/excalidraw": "0.17.6", "@excalidraw/laser-pointer": "1.3.1", - "@types/react": "18.3.10", + "@types/react": "18.3.11", "@types/react-dom": "18.3.0", "browser-fs-access": "0.35.0", "jotai": "2.10.0", @@ -17,7 +17,7 @@ }, "devDependencies": { "esbuild": "^0.24.0", - "typescript": "^5.6.2" + "typescript": "^5.6.3" } }, "node_modules/@esbuild/aix-ppc64": { @@ -424,9 +424,9 @@ "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" }, "node_modules/@types/react": { - "version": "18.3.10", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.10.tgz", - "integrity": "sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==", + "version": "18.3.11", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", + "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -592,9 +592,9 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/frontend/typescript/excalidraw_canvas/package.json b/frontend/typescript/excalidraw_canvas/package.json index 5f31741..376376f 100644 --- a/frontend/typescript/excalidraw_canvas/package.json +++ b/frontend/typescript/excalidraw_canvas/package.json @@ -2,7 +2,7 @@ "dependencies": { "@excalidraw/excalidraw": "0.17.6", "@excalidraw/laser-pointer": "1.3.1", - "@types/react": "18.3.10", + "@types/react": "18.3.11", "@types/react-dom": "18.3.0", "browser-fs-access": "0.35.0", "jotai": "2.10.0", @@ -12,6 +12,6 @@ }, "devDependencies": { "esbuild": "^0.24.0", - "typescript": "^5.6.2" + "typescript": "^5.6.3" } }