mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Adding the Assistant font, dynamic styling improvements, frame export colors, Removing ExcalidrawRef
This commit is contained in:
@@ -5,7 +5,11 @@ import { ExcalidrawElement, ExcalidrawImageElement, FileId } from "@zsviczian/ex
|
||||
import { BinaryFileData, DataURL } from "@zsviczian/excalidraw/types/types";
|
||||
import { App, MarkdownRenderer, Notice, TFile } from "obsidian";
|
||||
import {
|
||||
ASSISTANT_FONT,
|
||||
CASCADIA_FONT,
|
||||
VIRGIL_FONT,
|
||||
} from "./constFonts";
|
||||
import {
|
||||
DEFAULT_MD_EMBED_CSS,
|
||||
fileid,
|
||||
FRONTMATTER_KEY_BORDERCOLOR,
|
||||
@@ -15,7 +19,6 @@ import {
|
||||
IMAGE_TYPES,
|
||||
nanoid,
|
||||
THEME_FILTER,
|
||||
VIRGIL_FONT,
|
||||
} from "./constants";
|
||||
import { createSVG } from "./ExcalidrawAutomate";
|
||||
import { ExcalidrawData, getTransclusion } from "./ExcalidrawData";
|
||||
@@ -743,6 +746,9 @@ export class EmbeddedFilesLoader {
|
||||
case "Cascadia":
|
||||
fontDef = CASCADIA_FONT;
|
||||
break;
|
||||
case "Assistant":
|
||||
fontDef = ASSISTANT_FONT;
|
||||
break;
|
||||
case "":
|
||||
fontDef = "";
|
||||
break;
|
||||
|
||||
@@ -1570,12 +1570,12 @@ export class ExcalidrawAutomate {
|
||||
errorMessage("targetView not set", "deleteViewElements()");
|
||||
return false;
|
||||
}
|
||||
const current = this.targetView?.excalidrawRef?.current;
|
||||
if (!current) {
|
||||
const api = this.targetView?.excalidrawAPI as ExcalidrawImperativeAPI;
|
||||
if (!api) {
|
||||
return false;
|
||||
}
|
||||
const el: ExcalidrawElement[] = current.getSceneElements();
|
||||
const st: AppState = current.getAppState();
|
||||
const el: ExcalidrawElement[] = api.getSceneElements() as ExcalidrawElement[];
|
||||
const st: AppState = api.getAppState();
|
||||
this.targetView.updateScene({
|
||||
elements: el.filter((e: ExcalidrawElement) => !elToDelete.includes(e)),
|
||||
appState: st,
|
||||
|
||||
@@ -238,7 +238,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
public addText: Function = null;
|
||||
public addLink: Function = null;
|
||||
private refresh: Function = null;
|
||||
public excalidrawRef: React.MutableRefObject<any> = null;
|
||||
//public excalidrawRef: React.MutableRefObject<any> = null;
|
||||
public excalidrawAPI: any = null;
|
||||
public excalidrawWrapperRef: React.MutableRefObject<any> = null;
|
||||
public toolsPanelRef: React.MutableRefObject<any> = null;
|
||||
@@ -1165,7 +1165,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const api = this.excalidrawAPI;
|
||||
if (
|
||||
!this.plugin.settings.zoomToFitOnResize ||
|
||||
!this.excalidrawRef ||
|
||||
!this.excalidrawAPI ||
|
||||
this.semaphores.isEditingText ||
|
||||
!api
|
||||
) {
|
||||
@@ -1369,7 +1369,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
|
||||
public setTheme(theme: string) {
|
||||
const api = this.excalidrawAPI;
|
||||
if (!this.excalidrawRef || !api) {
|
||||
if (!api) {
|
||||
return;
|
||||
}
|
||||
if (this.file) {
|
||||
@@ -1451,7 +1451,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
st.draggingElement === null //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/630
|
||||
) {
|
||||
this.autosaveTimer = null;
|
||||
if (this.excalidrawRef) {
|
||||
if (this.excalidrawAPI) {
|
||||
this.semaphores.autosaving = true;
|
||||
const self = this;
|
||||
//changed from await to then to avoid lag during saving of large file
|
||||
@@ -1544,7 +1544,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
return;
|
||||
}
|
||||
const api = this.excalidrawAPI;
|
||||
if (!this.excalidrawRef || !this.file || !api) {
|
||||
if (!this.file || !api) {
|
||||
return;
|
||||
}
|
||||
const loadOnModifyTrigger = file && file === this.file;
|
||||
@@ -1686,7 +1686,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
|
||||
delete this.exportDialog;
|
||||
const api = this.excalidrawAPI;
|
||||
if (!this.excalidrawRef || !api) {
|
||||
if (!api) {
|
||||
return;
|
||||
}
|
||||
if (this.activeLoader) {
|
||||
@@ -2110,7 +2110,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
files: excalidrawData.files,
|
||||
libraryItems: await this.getLibrary(),
|
||||
});
|
||||
//files are loaded on excalidrawRef readyPromise
|
||||
//files are loaded when excalidrawAPI is mounted
|
||||
}
|
||||
const isCompressed = this.data.match(/```compressed\-json\n/gm) !== null;
|
||||
|
||||
@@ -2448,6 +2448,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
this.obsidianMenu = new ObsidianMenu(this.plugin, toolsPanelRef, this);
|
||||
this.embeddableMenu = new EmbeddableMenu(this, embeddableMenuRef);
|
||||
|
||||
|
||||
/*
|
||||
//excalidrawRef readypromise based on
|
||||
//https://codesandbox.io/s/eexcalidraw-resolvable-promise-d0qg3?file=/src/App.js:167-760
|
||||
const resolvablePromise = () => {
|
||||
@@ -2473,8 +2475,19 @@ export default class ExcalidrawView extends TextFileView {
|
||||
}),
|
||||
[],
|
||||
);
|
||||
*/
|
||||
|
||||
React.useEffect(() => {
|
||||
const setExcalidrawAPI = (api: ExcalidrawImperativeAPI) => {
|
||||
this.excalidrawAPI = api;
|
||||
api.setLocalFont(this.plugin.settings.experimentalEnableFourthFont);
|
||||
setTimeout(() => {
|
||||
this.onAfterLoadScene();
|
||||
this.excalidrawContainer = this.excalidrawWrapperRef?.current?.firstElementChild;
|
||||
this.excalidrawContainer?.focus();
|
||||
});
|
||||
};
|
||||
|
||||
/* React.useEffect(() => {
|
||||
excalidrawRef.current.readyPromise.then(
|
||||
(api: ExcalidrawImperativeAPI) => {
|
||||
this.excalidrawAPI = api;
|
||||
@@ -2486,14 +2499,14 @@ export default class ExcalidrawView extends TextFileView {
|
||||
});
|
||||
},
|
||||
);
|
||||
}, [excalidrawRef]);
|
||||
}, [excalidrawRef]);*/
|
||||
|
||||
this.excalidrawRef = excalidrawRef;
|
||||
// this.excalidrawRef = excalidrawRef;
|
||||
this.excalidrawWrapperRef = excalidrawWrapperRef;
|
||||
|
||||
const setCurrentPositionToCenter = () => {
|
||||
const api = this.excalidrawAPI;
|
||||
if (!excalidrawRef || !excalidrawRef.current || !api) {
|
||||
if (!api) {
|
||||
return;
|
||||
}
|
||||
const st = api.getAppState();
|
||||
@@ -2538,7 +2551,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
|
||||
this.getSelectedTextElement = (): SelectedElementWithLink => {
|
||||
const api = this.excalidrawAPI;
|
||||
if (!excalidrawRef?.current || !api) {
|
||||
if (!api) {
|
||||
return { id: null, text: null };
|
||||
}
|
||||
if (api.getAppState().viewModeEnabled) {
|
||||
@@ -2720,7 +2733,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
save: boolean = true
|
||||
): Promise<string> => {
|
||||
const api = this.excalidrawAPI as ExcalidrawImperativeAPI;
|
||||
if (!excalidrawRef?.current || !api) {
|
||||
if (!api) {
|
||||
return;
|
||||
}
|
||||
const st: AppState = api.getAppState();
|
||||
@@ -2763,7 +2776,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
shouldRestoreElements: boolean = false,
|
||||
): Promise<boolean> => {
|
||||
const api = this.excalidrawAPI as ExcalidrawImperativeAPI;
|
||||
if (!excalidrawRef?.current || !api) {
|
||||
if (!api) {
|
||||
return false;
|
||||
}
|
||||
const textElements = newElements.filter((el) => el.type == "text");
|
||||
@@ -2869,7 +2882,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
|
||||
this.getScene = (selectedOnly?: boolean) => {
|
||||
const api = this.excalidrawAPI;
|
||||
if (!excalidrawRef?.current || !api) {
|
||||
if (!api) {
|
||||
return null;
|
||||
}
|
||||
const el: ExcalidrawElement[] = selectedOnly ? this.getViewSelectedElements() : api.getSceneElements();
|
||||
@@ -2925,7 +2938,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
this.refresh = () => {
|
||||
if(this.contentEl.clientWidth === 0 || this.contentEl.clientHeight === 0) return;
|
||||
const api = this.excalidrawAPI;
|
||||
if (!excalidrawRef?.current || !api) {
|
||||
if (!api) {
|
||||
return;
|
||||
}
|
||||
api.refresh();
|
||||
@@ -4431,7 +4444,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
React.createElement(
|
||||
Excalidraw,
|
||||
{
|
||||
ref: excalidrawRef,
|
||||
excalidrawAPI: ((api: ExcalidrawImperativeAPI) =>{setExcalidrawAPI(api)}),
|
||||
width: dimensions.width,
|
||||
height: dimensions.height,
|
||||
UIOptions:
|
||||
@@ -4522,7 +4535,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const modalContainer = document.body.querySelector("div.modal-container");
|
||||
if(modalContainer) return; //do not autozoom when the command palette or other modal container is envoked on iPad
|
||||
const api = this.excalidrawAPI;
|
||||
if (!api || !this.excalidrawRef || this.semaphores.isEditingText || this.semaphores.preventAutozoom) {
|
||||
if (!api || this.semaphores.isEditingText || this.semaphores.preventAutozoom) {
|
||||
return;
|
||||
}
|
||||
const maxZoom = this.plugin.settings.zoomToFitMaxLevel;
|
||||
|
||||
6
src/constFonts.ts
Normal file
6
src/constFonts.ts
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
10
src/main.ts
10
src/main.ts
@@ -38,13 +38,15 @@ import {
|
||||
DARK_BLANK_DRAWING,
|
||||
SCRIPT_INSTALL_CODEBLOCK,
|
||||
SCRIPT_INSTALL_FOLDER,
|
||||
VIRGIL_FONT,
|
||||
VIRGIL_DATAURL,
|
||||
EXPORT_TYPES,
|
||||
EXPORT_IMG_ICON_NAME,
|
||||
EXPORT_IMG_ICON,
|
||||
LOCALE,
|
||||
} from "./constants";
|
||||
import {
|
||||
VIRGIL_FONT,
|
||||
VIRGIL_DATAURL,
|
||||
} from "./constFonts";
|
||||
import ExcalidrawView, { TextMode, getTextMode } from "./ExcalidrawView";
|
||||
import {
|
||||
changeThemeOfExcalidrawMD,
|
||||
@@ -693,7 +695,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
const leaves = this.app.workspace.getLeavesOfType(VIEW_TYPE_EXCALIDRAW);
|
||||
leaves.forEach((leaf: WorkspaceLeaf) => {
|
||||
const excalidrawView = leaf.view as ExcalidrawView;
|
||||
if (excalidrawView.file && excalidrawView.excalidrawRef) {
|
||||
if (excalidrawView.file && excalidrawView.excalidrawAPI) {
|
||||
excalidrawView.setTheme(theme);
|
||||
}
|
||||
});
|
||||
@@ -1488,7 +1490,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
checkCallback: (checking: boolean) => {
|
||||
if (checking) {
|
||||
const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
|
||||
if (!view || !view.excalidrawRef) {
|
||||
if (!view || !view.excalidrawAPI) {
|
||||
return false;
|
||||
}
|
||||
const st = view.excalidrawAPI.getAppState();
|
||||
|
||||
@@ -1582,6 +1582,7 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
.addDropdown(async (d: DropdownComponent) => {
|
||||
d.addOption("Virgil", "Virgil");
|
||||
d.addOption("Cascadia", "Cascadia");
|
||||
d.addOption("Assistant", "Assistant");
|
||||
this.app.vault
|
||||
.getFiles()
|
||||
.filter((f) => ["ttf", "woff", "woff2"].contains(f.extension))
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import { ExcalidrawImperativeAPI } from "@zsviczian/excalidraw/types/types";
|
||||
import { ColorMaster } from "colormaster";
|
||||
import { ExcalidrawAutomate } from "src/ExcalidrawAutomate";
|
||||
import ExcalidrawView from "src/ExcalidrawView";
|
||||
import { DynamicStyle } from "src/types";
|
||||
import { cloneElement } from "src/ExcalidrawAutomate";
|
||||
import { ExcalidrawFrameElement } from "@zsviczian/excalidraw/types/element/types";
|
||||
import { addAppendUpdateCustomData } from "./Utils";
|
||||
import { mutateElement } from "src/constants";
|
||||
|
||||
export const setDynamicStyle = (
|
||||
ea: ExcalidrawAutomate,
|
||||
@@ -55,57 +60,59 @@ export const setDynamicStyle = (
|
||||
const cmBlack = () => ea.getCM("#000000").lightnessTo(bgLightness);
|
||||
|
||||
|
||||
const gray1 = isGray
|
||||
const gray1 = () => isGray
|
||||
? isDark ? cmBlack().lighterBy(10) : cmBlack().darkerBy(10)
|
||||
: isDark ? cmBG().lighterBy(10).mix({color:cmBlack(),ratio:0.5}) : cmBG().darkerBy(10).mix({color:cmBlack(),ratio:0.5});
|
||||
const gray2 = isGray
|
||||
const gray2 = () => isGray
|
||||
? isDark ? cmBlack().lighterBy(4) : cmBlack().darkerBy(4)
|
||||
: isDark ? cmBG().lighterBy(4).mix({color:cmBlack(),ratio:0.5}) : cmBG().darkerBy(4).mix({color:cmBlack(),ratio:0.5});
|
||||
|
||||
|
||||
const text = cmBG().mix({color:isDark?lighter:darker, ratio:mixRatio});
|
||||
|
||||
const str = (cm: ColorMaster) => cm.stringHEX({alpha:false});
|
||||
const styleObject:{[x: string]: string;} = {
|
||||
[`--color-primary`]: str(accent()),
|
||||
[`--color-surface-low`]: str(gray1),
|
||||
[`--color-surface-mid`]: str(gray1),
|
||||
[`--color-surface-lowest`]: str(gray2),
|
||||
[`--color-surface-high`]: str(gray1.lighterBy(step)),
|
||||
[`--color-surface-low`]: str(gray1()),
|
||||
[`--color-surface-mid`]: str(gray1()),
|
||||
[`--color-surface-lowest`]: str(gray2()),
|
||||
[`--color-surface-high`]: str(gray1().lighterBy(step)),
|
||||
[`--color-on-primary-container`]: str(!isDark?accent().darkerBy(15):accent().lighterBy(15)),
|
||||
[`--color-surface-primary-container`]: str(isDark?accent().darkerBy(step):accent().lighterBy(step)),
|
||||
//[`--color-primary-darker`]: str(accent().darkerBy(step)),
|
||||
//[`--color-primary-darkest`]: str(accent().darkerBy(step)),
|
||||
[`--button-gray-1`]: str(gray1),
|
||||
[`--button-gray-2`]: str(gray2),
|
||||
[`--input-border-color`]: str(gray1),
|
||||
[`--input-bg-color`]: str(gray2),
|
||||
[`--button-gray-1`]: str(gray1()),
|
||||
[`--button-gray-2`]: str(gray2()),
|
||||
[`--input-border-color`]: str(gray1()),
|
||||
[`--input-bg-color`]: str(gray2()),
|
||||
[`--input-label-color`]: str(text),
|
||||
[`--island-bg-color`]: gray2.alphaTo(0.93).stringHEX(),
|
||||
[`--popup-secondary-bg-color`]: gray2.alphaTo(0.93).stringHEX(),
|
||||
[`--island-bg-color`]: gray2().alphaTo(0.93).stringHEX(),
|
||||
[`--popup-secondary-bg-color`]: gray2().alphaTo(0.93).stringHEX(),
|
||||
[`--icon-fill-color`]: str(text),
|
||||
[`--text-primary-color`]: str(text),
|
||||
[`--overlay-bg-color`]: gray2.alphaTo(0.6).stringHEX(),
|
||||
[`--popup-bg-color`]: str(gray1),
|
||||
[`--overlay-bg-color`]: gray2().alphaTo(0.6).stringHEX(),
|
||||
[`--popup-bg-color`]: str(gray1()),
|
||||
[`--color-on-surface`]: str(text),
|
||||
//[`--color-gray-100`]: str(text),
|
||||
[`--color-gray-40`]: str(text), //frame
|
||||
[`--color-gray-50`]: str(text), //frame
|
||||
[`--color-surface-highlight`]: str(gray1),
|
||||
[`--color-surface-highlight`]: str(gray1()),
|
||||
//[`--color-gray-30`]: str(gray1),
|
||||
[`--color-gray-80`]: str(isDark?text.lighterBy(15):text.darkerBy(15)), //frame
|
||||
[`--sidebar-border-color`]: str(gray1),
|
||||
[`--sidebar-border-color`]: str(gray1()),
|
||||
[`--color-primary-light`]: str(accent().lighterBy(step)),
|
||||
[`--button-hover-bg`]: str(gray1),
|
||||
[`--sidebar-bg-color`]: gray2.alphaTo(0.93).stringHEX(),
|
||||
[`--sidebar-shadow`]: str(gray1),
|
||||
[`--button-hover-bg`]: str(gray1()),
|
||||
[`--sidebar-bg-color`]: gray2().alphaTo(0.93).stringHEX(),
|
||||
[`--sidebar-shadow`]: str(gray1()),
|
||||
[`--popup-text-color`]: str(text),
|
||||
[`--code-normal`]: str(text),
|
||||
[`--code-background`]: str(gray2),
|
||||
[`--code-background`]: str(gray2()),
|
||||
[`--h1-color`]: str(text),
|
||||
[`--h2-color`]: str(text),
|
||||
[`--h3-color`]: str(text),
|
||||
[`--h4-color`]: str(text),
|
||||
[`color`]: str(text),
|
||||
[`--select-highlight-color`]: str(gray1),
|
||||
[`--select-highlight-color`]: str(gray1()),
|
||||
};
|
||||
|
||||
const styleString = Object.keys(styleObject)
|
||||
@@ -117,13 +124,36 @@ export const setDynamicStyle = (
|
||||
styleString
|
||||
)*/
|
||||
|
||||
setTimeout(()=>view.updateScene({appState:{
|
||||
frameColor: {
|
||||
stroke: isDark?str(gray2.lighterBy(15)):str(gray2.darkerBy(15)),
|
||||
fill: str((isDark?gray2.lighterBy(30):gray2.darkerBy(30)).alphaTo(0.2)),
|
||||
},
|
||||
dynamicStyle: styleObject
|
||||
}}));
|
||||
setTimeout(()=>{
|
||||
const api = view.excalidrawAPI as ExcalidrawImperativeAPI;
|
||||
if(!api) return;
|
||||
const frameColor = {
|
||||
stroke: str(isDark?gray2().lighterBy(15):gray2().darkerBy(15)),
|
||||
fill: str((isDark?gray2().lighterBy(30):gray2().darkerBy(30)).alphaTo(0.2)),
|
||||
nameColor: str(isDark?gray2().lighterBy(40):gray2().darkerBy(40)),
|
||||
}
|
||||
const scene = api.getSceneElements();
|
||||
scene.filter(el=>el.type==="frame").forEach((e:ExcalidrawFrameElement)=>{
|
||||
const f = cloneElement(e);
|
||||
addAppendUpdateCustomData(f,{frameColor});
|
||||
if(
|
||||
e.customData && e.customData.frameColor &&
|
||||
e.customData.frameColor.stroke === frameColor.stroke &&
|
||||
e.customData.frameColor.fill === frameColor.fill &&
|
||||
e.customData.frameColor.nameColor === frameColor.nameColor
|
||||
) {
|
||||
return;
|
||||
}
|
||||
mutateElement(e,{customData: f.customData});
|
||||
});
|
||||
|
||||
view.updateScene({
|
||||
appState:{
|
||||
frameColor,
|
||||
dynamicStyle: styleObject
|
||||
}
|
||||
});
|
||||
});
|
||||
const toolspanel = view.toolsPanelRef?.current?.containerRef?.current;
|
||||
if(toolspanel) {
|
||||
let toolsStyle = toolspanel.getAttribute("style");
|
||||
|
||||
@@ -10,8 +10,11 @@ import {
|
||||
import { Random } from "roughjs/bin/math";
|
||||
import { BinaryFileData, DataURL} from "@zsviczian/excalidraw/types/types";
|
||||
import {
|
||||
ASSISTANT_FONT,
|
||||
CASCADIA_FONT,
|
||||
VIRGIL_FONT,
|
||||
} from "src/constFonts";
|
||||
import {
|
||||
FRONTMATTER_KEY_EXPORT_DARK,
|
||||
FRONTMATTER_KEY_EXPORT_TRANSPARENT,
|
||||
FRONTMATTER_KEY_EXPORT_SVGPADDING,
|
||||
@@ -371,12 +374,15 @@ export const embedFontsInSVG = (
|
||||
svg.querySelector("text[font-family^='Virgil']") != null;
|
||||
const includesCascadia = !localOnly &&
|
||||
svg.querySelector("text[font-family^='Cascadia']") != null;
|
||||
const includesAssistant = !localOnly &&
|
||||
svg.querySelector("text[font-family^='Assistant']") != null;
|
||||
const includesLocalFont =
|
||||
svg.querySelector("text[font-family^='LocalFont']") != null;
|
||||
const defs = svg.querySelector("defs");
|
||||
if (defs && (includesCascadia || includesVirgil || includesLocalFont)) {
|
||||
if (defs && (includesCascadia || includesVirgil || includesLocalFont || includesAssistant)) {
|
||||
defs.innerHTML = `<style>${includesVirgil ? VIRGIL_FONT : ""}${
|
||||
includesCascadia ? CASCADIA_FONT : ""
|
||||
includesCascadia ? CASCADIA_FONT : ""}${
|
||||
includesAssistant ? ASSISTANT_FONT : ""
|
||||
}${includesLocalFont ? plugin.fourthFontDef : ""}</style>`;
|
||||
}
|
||||
return svg;
|
||||
|
||||
Reference in New Issue
Block a user