mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
164 lines
4.6 KiB
TypeScript
164 lines
4.6 KiB
TypeScript
import { TextFileView, WorkspaceLeaf } from "obsidian";
|
|
import * as React from "react";
|
|
import * as ReactDOM from "react-dom";
|
|
import Excalidraw, {exportToSvg} from "@excalidraw/excalidraw";
|
|
import { ExcalidrawElement } from "@excalidraw/excalidraw/types/element/types";
|
|
import { AppState } from "@excalidraw/excalidraw/types/types";
|
|
|
|
|
|
export default class ExcalidrawView extends TextFileView {
|
|
private getScene: any;
|
|
|
|
constructor(leaf: WorkspaceLeaf) {
|
|
super(leaf);
|
|
this.getScene = null;
|
|
}
|
|
|
|
async onClose() {
|
|
this.requestSave();
|
|
}
|
|
|
|
|
|
|
|
// clear the view content
|
|
clear() {
|
|
ReactDOM.unmountComponentAtNode(this.contentEl);
|
|
this.getScene = null;
|
|
}
|
|
|
|
// get the new file content
|
|
getViewData () {
|
|
if(this.getScene) return this.getScene();
|
|
else return '';
|
|
}
|
|
|
|
|
|
|
|
setViewData (data: string, clear: boolean) {
|
|
if (this.app.workspace.layoutReady) {
|
|
this.loadDrawing(data,clear);
|
|
} else {
|
|
this.registerEvent(this.app.workspace.on('layout-ready', async () => this.loadDrawing(data,clear)));
|
|
}
|
|
}
|
|
|
|
private loadDrawing (data:string, clear:boolean) :void {
|
|
if(clear) this.clear();
|
|
const excalidrawData = JSON.parse(data);
|
|
this.instantiateExcalidraw({
|
|
elements: excalidrawData.elements,
|
|
appState: excalidrawData.appState,
|
|
scrollToContent: true,
|
|
});
|
|
}
|
|
|
|
// gets the title of the document
|
|
getDisplayText() {
|
|
if(this.file) return this.file.basename;
|
|
else return "excalidraw (no file)";
|
|
|
|
}
|
|
|
|
// confirms this view can accept csv extension
|
|
canAcceptExtension(extension: string) {
|
|
return extension == 'excalidraw';
|
|
}
|
|
|
|
// the view type name
|
|
getViewType() {
|
|
return "excalidraw";
|
|
}
|
|
|
|
// icon for the view
|
|
getIcon() {
|
|
return "document-excalidraw";
|
|
}
|
|
|
|
private instantiateExcalidraw(initdata: any) {
|
|
ReactDOM.render(React.createElement(() => {
|
|
let previousSceneVersion = 0;
|
|
const excalidrawRef = React.useRef(null);
|
|
const excalidrawWrapperRef = React.useRef(null);
|
|
const [dimensions, setDimensions] = React.useState({
|
|
width: undefined,
|
|
height: undefined
|
|
});
|
|
|
|
React.useEffect(() => {
|
|
setDimensions({
|
|
width: this.contentEl.clientWidth,
|
|
height: this.contentEl.clientHeight,
|
|
});
|
|
const onResize = () => {
|
|
try {
|
|
setDimensions({
|
|
width: this.contentEl.clientWidth,
|
|
height: this.contentEl.clientHeight,
|
|
});
|
|
} catch(err) {console.log ("onResize ",err)}
|
|
};
|
|
window.addEventListener("resize", onResize);
|
|
return () => window.removeEventListener("resize", onResize);
|
|
}, [excalidrawWrapperRef]);
|
|
|
|
this.getScene = function() {
|
|
const el: ExcalidrawElement[] = excalidrawRef.current.getSceneElements();
|
|
const st: AppState = excalidrawRef.current.getAppState();
|
|
return JSON.stringify({
|
|
"type": "excalidraw",
|
|
"version": 2,
|
|
"source": "https://excalidraw.com",
|
|
"elements": el.filter(e => !e.isDeleted),
|
|
"appState": {
|
|
"theme": st.theme,
|
|
"viewBackgroundColor": st.viewBackgroundColor,
|
|
"gridSize": st.gridSize,
|
|
"zenModeEnabled": st.zenModeEnabled
|
|
}
|
|
});
|
|
};
|
|
|
|
return React.createElement(
|
|
React.Fragment,
|
|
null,
|
|
React.createElement(
|
|
"div",
|
|
{
|
|
className: "excalidraw-wrapper",
|
|
ref: excalidrawWrapperRef
|
|
},
|
|
React.createElement(Excalidraw.default, {
|
|
ref: excalidrawRef,
|
|
width: dimensions.width,
|
|
height: dimensions.height,
|
|
UIOptions: {
|
|
canvasActions: {
|
|
loadScene: false,
|
|
saveScene: false,
|
|
saveAsScene: false
|
|
},
|
|
},
|
|
initialData: initdata
|
|
})
|
|
)
|
|
);
|
|
}),(this as any).contentEl);
|
|
}
|
|
|
|
public static getSVG(data:string):SVGSVGElement {
|
|
try {
|
|
const excalidrawData = JSON.parse(data);
|
|
return exportToSvg({
|
|
elements: excalidrawData.elements,
|
|
appState: {
|
|
exportBackground: true,
|
|
exportWithDarkMode: excalidrawData.appState?.theme=="light" ? false : true,
|
|
... excalidrawData.appState,},
|
|
exportPadding:10,
|
|
metadata: "Generated by Excalidraw-Obsidian plugin",
|
|
});
|
|
} catch (error) {
|
|
return null;
|
|
}
|
|
}
|
|
} |