This commit is contained in:
zsviczian
2023-07-25 23:07:34 +02:00
parent bb2d30f9e3
commit 2eb5fc476c
14 changed files with 216 additions and 17 deletions

View File

@@ -50,8 +50,10 @@ const startFullscreen = !altKey;
//For this reason event handlers are distributed between window and owner window depending on their role
const ownerWindow = ea.targetView.ownerWindow;
const excalidrawAPI = ea.getExcalidrawAPI();
const frameRenderingOriginalState = excalidrawAPI.getAppState().frameRendering;
const contentEl = ea.targetView.contentEl;
const sleep = async (ms) => new Promise((resolve) => ownerWindow.setTimeout(resolve, ms));
const getFrameName = (name, index) => name ?? `Frame ${(index+1).toString().padStart(2, '0')}`;
//-------------------------------
//clean up potential clutter from previous run
@@ -63,9 +65,10 @@ let presentationPathLineEl = ea.getViewElements()
.filter(el=>["line","arrow"].contains(el.type) && el.customData?.slideshow)[0];
let frames = ea.getViewElements()
.filter(el=>el.type==="frame")
.map((f,i)=>[f,i]) //because frame.name is null until set
.sort((el1,el2)=>((el1[0].name??`Frame ${el1[1]}`)>(el2[0].name??`Frame ${el2[1]}`))?1:-1)
.map((frame,index)=>[frame,index]) //because frame.name is null until set
.sort((el1,el2)=> getFrameName(el1[0], el1[1]) > getFrameName(el2[0], el2[1]) ? -1:1)
.map(el=>el[0]);
let presentationPathType = "line"; // "frame"
const selectedEl = ea.getViewSelectedElement();
let shouldHideArrowAfterPresentation = true; //this controls if the hide arrow button is available in settings
@@ -124,7 +127,16 @@ if(presentationPathType === "frame") {
y2: frame.y + frame.height
});
}
excalidrawAPI.updateScene({appState:{shouldRenderFrames:false}});
if(frameRenderingOriginalState.enabled) {
excalidrawAPI.updateScene({
appState: {
frameRendering: {
...frameRenderingOriginalState,
enabled: false
}
}
});
}
}
//---------------------------------------
@@ -406,7 +418,9 @@ const createPresentationNavigationPanel = () => {
}, selectEl => {
for (let i = 0; i < slides.length; i++) {
const option = document.createElement("option");
option.text = `Slide ${i + 1}/${slides.length}`;
option.text = (presentationPathType === "frame")
? `${getFrameName(frames[i]?.name,i)}/${slides.length}`
: option.text = `Slide ${i + 1}/${slides.length}`;
option.value = i + 1;
selectEl.add(option);
}
@@ -647,7 +661,16 @@ const exitPresentation = async (openForEdit = false) => {
);
}
} else {
excalidrawAPI.updateScene({appState:{shouldRenderFrames:true}});
if(frameRenderingOriginalState.enabled) {
excalidrawAPI.updateScene({
appState: {
frameRendering: {
...frameRenderingOriginalState,
enabled: true
}
}
});
}
}
window.removePresentationEventHandlers?.();
ownerWindow.setTimeout(()=>{

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{
"id": "obsidian-excalidraw-plugin",
"name": "Excalidraw",
"version": "1.9.10",
"version": "1.9.11",
"minAppVersion": "1.1.6",
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian",

View File

@@ -18,7 +18,7 @@
"license": "MIT",
"dependencies": {
"@types/lz-string": "^1.3.34",
"@zsviczian/excalidraw": "0.15.2-obsidian-9",
"@zsviczian/excalidraw": "0.15.2-obsidian-10",
"chroma-js": "^2.4.2",
"clsx": "^1.2.1",
"colormaster": "^1.2.1",

View File

@@ -30,6 +30,7 @@ import {
intersectElementWithLine,
measureText,
DEVICE,
restore,
} from "src/Constants";
import { getDrawingFilename, getNewUniqueFilepath, } from "src/utils/FileUtils";
import {
@@ -2607,7 +2608,7 @@ export function repositionElementsToCursor(
element.y = element.y + offsetY;
});
return api.restore({elements}).elements;
return restore({elements}, null, null).elements;
}
function errorMessage(message: string, source: string) {

View File

@@ -719,7 +719,7 @@ export class ExcalidrawData {
wrapAt ? wrapText(
originalText,
getFontString({fontSize: te.fontSize, fontFamily: te.fontFamily}),
getBoundTextMaxWidth(container)
getBoundTextMaxWidth(container as any)
) : originalText,
originalText,
forceupdate,

116
src/ExcalidrawLib.d.ts vendored Normal file
View File

@@ -0,0 +1,116 @@
import { RestoredDataState } from "@zsviczian/excalidraw/types/data/restore";
import { ImportedDataState } from "@zsviczian/excalidraw/types/data/types";
import { BoundingBox } from "@zsviczian/excalidraw/types/element/bounds";
import { ExcalidrawBindableElement, ExcalidrawElement, ExcalidrawTextElement, FontFamilyValues, FontString, NonDeleted } from "@zsviczian/excalidraw/types/element/types";
import { AppState, BinaryFiles, ExportOpts, Point, Zoom } from "@zsviczian/excalidraw/types/types";
import { Mutable } from "@zsviczian/excalidraw/types/utility-types";
declare namespace ExcalidrawLib {
type ElementUpdate<TElement extends ExcalidrawElement> = Omit<
Partial<TElement>,
"id" | "version" | "versionNonce"
>;
type ExportOpts = {
elements: readonly NonDeleted<ExcalidrawElement>[];
appState?: Partial<Omit<AppState, "offsetTop" | "offsetLeft">>;
files: BinaryFiles | null;
maxWidthOrHeight?: number;
getDimensions?: (
width: number,
height: number,
) => { width: number; height: number; scale?: number };
};
function restore(
data: Pick<ImportedDataState, "appState" | "elements" | "files"> | null,
localAppState: Partial<AppState> | null | undefined,
localElements: readonly ExcalidrawElement[] | null | undefined,
elementsConfig?: { refreshDimensions?: boolean; repairBindings?: boolean },
): RestoredDataState;
function exportToSvg(opts: Omit<ExportOpts, "getDimensions"> & {
elements: ExcalidrawElement[];
appState?: AppState;
files?: any;
exportPadding?: number;
renderEmbeddables?: boolean;
}): Promise<SVGSVGElement>;
function sceneCoordsToViewportCoords(
sceneCoords: { sceneX: number; sceneY: number },
viewParams: {
zoom: Zoom;
offsetLeft: number;
offsetTop: number;
scrollX: number;
scrollY: number;
},
): { x: number; y: number };
function viewportCoordsToSceneCoords(
viewportCoords: { clientX: number; clientY: number },
viewParams: {
zoom: Zoom;
offsetLeft: number;
offsetTop: number;
scrollX: number;
scrollY: number;
},
): { x: number; y: number };
function determineFocusDistance(
element: ExcalidrawBindableElement,
a: Point,
b: Point,
): number;
function intersectElementWithLine(
element: ExcalidrawBindableElement,
a: Point,
b: Point,
gap?: number,
): Point[];
function getCommonBoundingBox(
elements: ExcalidrawElement[] | readonly NonDeleted<ExcalidrawElement>[],
): BoundingBox;
function getMaximumGroups(
elements: ExcalidrawElement[],
): ExcalidrawElement[][];
function measureText(
text: string,
font: FontString,
lineHeight: number,
): { width: number; height: number; baseline: number };
function getDefaultLineHeight(fontFamily: FontFamilyValues): number;
function wrapText(text: string, font: FontString, maxWidth: number): string;
function getFontString({
fontSize,
fontFamily,
}: {
fontSize: number;
fontFamily: FontFamilyValues;
}): FontString;
function getBoundTextMaxWidth(container: ExcalidrawElement): number;
function exportToBlob(
opts: ExportOpts & {
mimeType?: string;
quality?: number;
exportPadding?: number;
},
): Promise<Blob>;
function mutateElement<TElement extends Mutable<ExcalidrawElement>>(
element: TElement,
updates: ElementUpdate<TElement>,
informMutation?: boolean,
): TElement;
}

View File

@@ -9,7 +9,6 @@ import {
MarkdownView,
request,
requireApiVersion,
WorkspaceSplit,
} from "obsidian";
//import * as React from "react";
//import * as ReactDOM from "react-dom";
@@ -49,6 +48,7 @@ import {
EXPORT_IMG_ICON_NAME,
viewportCoordsToSceneCoords,
ERROR_IFRAME_CONVERSION_CANCELED,
restore,
} from "./Constants";
import ExcalidrawPlugin from "./main";
import {
@@ -774,6 +774,18 @@ export default class ExcalidrawView extends TextFileView {
new Notice(newState ? "Inverted Mode: Default arrow binding is now disabled. Use CTRL/CMD to temporarily enable binding when needed." : "Normal Mode: Arrow binding is now enabled. Use CTRL/CMD to temporarily disable binding when needed.");
}
toggleFrameRendering() {
const frameRenderingSt = (this.excalidrawAPI as ExcalidrawImperativeAPI).getAppState().frameRendering;
this.updateScene({appState: {frameRendering: {...frameRenderingSt, enabled: !frameRenderingSt.enabled}}});
new Notice(frameRenderingSt.enabled ? "Frame Rendering: Enabled" : "Frame Rendering: Disabled");
}
toggleFrameClipping() {
const frameRenderingSt = (this.excalidrawAPI as ExcalidrawImperativeAPI).getAppState().frameRendering;
this.updateScene({appState: {frameRendering: {...frameRenderingSt, clip: !frameRenderingSt.clip}}});
new Notice(frameRenderingSt.clip ? "Frame Clipping: Enabled" : "Frame Clipping: Disabled");
}
gotoFullscreen() {
if(this.plugin.leafChangeTimeout) {
clearTimeout(this.plugin.leafChangeTimeout);
@@ -2773,6 +2785,7 @@ export default class ExcalidrawView extends TextFileView {
colorPalette: st.colorPalette,
currentStrokeOptions: st.currentStrokeOptions,
previousGridSize: st.previousGridSize,
frameRendering: st.frameRendering,
},
prevTextMode: this.prevTextMode,
files,
@@ -4337,15 +4350,15 @@ export default class ExcalidrawView extends TextFileView {
files?: any;
commitToHistory?: boolean;
},
restore: boolean = false,
shouldRestore: boolean = false,
) {
const api = this.excalidrawAPI;
if (!api) {
return;
}
const shouldRestoreElements = scene.elements && restore;
const shouldRestoreElements = scene.elements && shouldRestore;
if (shouldRestoreElements) {
scene.elements = api.restore(scene).elements;
scene.elements = restore(scene, null, null).elements;
}
try {
api.updateScene(scene);
@@ -4360,7 +4373,7 @@ export default class ExcalidrawView extends TextFileView {
if (!shouldRestoreElements) {
//second attempt
try {
scene.elements = api.restore(scene).elements;
scene.elements = restore(scene, null, null).elements;
api.updateScene(scene);
} catch (e) {
errorlog({

View File

@@ -1,11 +1,14 @@
import { customAlphabet } from "nanoid";
import { DeviceType } from "./types";
import { Platform } from "obsidian";
import { ExcalidrawLib } from "./ExcalidrawLib";
//This is only for backward compatibility because an early version of obsidian included an encoding to avoid fantom links from littering Obsidian graph view
declare const PLUGIN_VERSION:string;
export const ERROR_IFRAME_CONVERSION_CANCELED = "iframe conversion canceled";
declare const excalidrawLib: typeof ExcalidrawLib;
export const {
sceneCoordsToViewportCoords,
viewportCoordsToSceneCoords,
@@ -21,7 +24,7 @@ export const {
exportToSvg,
exportToBlob,
mutateElement,
//@ts-ignore
restore,
} = excalidrawLib;
export function JSON_parse(x: string): any {

View File

@@ -17,6 +17,8 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
<div class="ex-coffee-div"><a href="https://ko-fi.com/zsolt"><img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" height=45></a></div>
`,
"1.9.11":`
`,
"1.9.10":`
## New
- @mazurov added a new script: [Ellipse Selected Elements](https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/master/ea-scripts/Ellipse%20Selected%20Elements.md)

View File

@@ -507,6 +507,8 @@ FILENAME_HEAD: "Filename",
EXIT_FULLSCREEN: "Exit fullscreen mode",
TOGGLE_FULLSCREEN: "Toggle fullscreen mode",
TOGGLE_DISABLEBINDING: "Toggle to invert default binding behavior",
TOGGLE_FRAME_RENDERING: "Toggle frame rendering",
TOGGLE_FRAME_CLIPPING: "Toggle frame clipping",
OPEN_LINK_CLICK: "Navigate to selected element link",
OPEN_LINK_PROPS: "Open markdown-embed properties or open link in new window",

View File

@@ -1019,6 +1019,43 @@ export default class ExcalidrawPlugin extends Plugin {
},
});
this.addCommand({
id: "disable-framerendering",
name: t("TOGGLE_FRAME_RENDERING"),
checkCallback: (checking: boolean) => {
if (checking) {
return (
Boolean(this.app.workspace.getActiveViewOfType(ExcalidrawView))
);
}
const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
if (view) {
view.toggleFrameRendering();
return true;
}
return false;
},
});
this.addCommand({
id: "disable-frameclipping",
name: t("TOGGLE_FRAME_CLIPPING"),
checkCallback: (checking: boolean) => {
if (checking) {
return (
Boolean(this.app.workspace.getActiveViewOfType(ExcalidrawView))
);
}
const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
if (view) {
view.toggleFrameClipping();
return true;
}
return false;
},
});
this.addCommand({
id: "export-image",
name: t("EXPORT_IMAGE"),

View File

@@ -1,5 +1,6 @@
import { GITHUB_RELEASES } from "src/Constants";
import { ExcalidrawGenericElement } from "./ExcalidrawElement";
declare const PLUGIN_VERSION:string;
class ExcalidrawScene {

View File

@@ -25,9 +25,10 @@ import { ExcalidrawElement } from "@zsviczian/excalidraw/types/element/types";
import { ExportSettings } from "../ExcalidrawView";
import { compressToBase64, decompressFromBase64 } from "lz-string";
import { getDataURLFromURL, getIMGFilename, getMimeType, getURLImageExtension } from "./FileUtils";
import ExcalidrawScene from "../svgToExcalidraw/elements/ExcalidrawScene";
import { IMAGE_TYPES } from "../Constants";
import { generateEmbeddableLink } from "./CustomEmbeddableUtils";
import Scene from "@zsviczian/excalidraw/types/scene/Scene";
import ExcalidrawScene from "src/svgToExcalidraw/elements/ExcalidrawScene";
declare const PLUGIN_VERSION:string;