Adding the Assistant font, dynamic styling improvements, frame export colors, Removing ExcalidrawRef

This commit is contained in:
zsviczian
2023-11-12 07:19:09 +01:00
parent 48466f624d
commit a35ea5e9da
9 changed files with 122 additions and 62 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -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();

View File

@@ -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))

View File

@@ -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");

View File

@@ -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;