mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
2 Commits
2.4.0-beta
...
2.4.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d529a04f48 | ||
|
|
8786c5aa99 |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.4.0-beta-4",
|
||||
"version": "2.4.0-beta-6",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@zsviczian/excalidraw": "0.17.1-obsidian-39",
|
||||
"@zsviczian/excalidraw": "0.17.1-obsidian-40",
|
||||
"chroma-js": "^2.4.2",
|
||||
"clsx": "^2.0.0",
|
||||
"colormaster": "^1.2.1",
|
||||
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
svgToBase64,
|
||||
isMaskFile,
|
||||
getEmbeddedFilenameParts,
|
||||
cropCanvas,
|
||||
} from "./utils/Utils";
|
||||
import { ValueOf } from "./types/types";
|
||||
import { getMermaidImageElements, getMermaidText, shouldRenderMermaid } from "./utils/MermaidUtils";
|
||||
@@ -746,6 +747,8 @@ export class EmbeddedFilesLoader {
|
||||
}
|
||||
const pageNum = isNaN(linkParts.page) ? 1 : (linkParts.page??1);
|
||||
const scale = this.plugin.settings.pdfScale;
|
||||
const cropRect = linkParts.ref.split("rect=")[1]?.split(",").map(x=>parseInt(x));
|
||||
const validRect = cropRect && cropRect.length === 4 && cropRect.every(x=>!isNaN(x));
|
||||
|
||||
// Render the page
|
||||
const renderPage = async (num:number) => {
|
||||
@@ -766,6 +769,23 @@ export class EmbeddedFilesLoader {
|
||||
};
|
||||
|
||||
await page.render(renderCtx).promise;
|
||||
if(validRect) {
|
||||
const [left, bottom, _, top] = page.view;
|
||||
|
||||
const pageHeight = top - bottom;
|
||||
width = (cropRect[2] - cropRect[0]) * scale;
|
||||
height = (cropRect[3] - cropRect[1]) * scale;
|
||||
|
||||
const crop = validRect ? {
|
||||
left: (cropRect[0] - left) * scale,
|
||||
top: (bottom + pageHeight - cropRect[3]) * scale,
|
||||
width,
|
||||
height,
|
||||
} : undefined;
|
||||
if(crop) {
|
||||
return cropCanvas(canvas, crop);
|
||||
}
|
||||
}
|
||||
return canvas;
|
||||
};
|
||||
|
||||
|
||||
@@ -3766,8 +3766,14 @@ export default class ExcalidrawView extends TextFileView {
|
||||
ea.selectElementsInView([await insertEmbeddableToView (ea, this.currentPosition, file, link)]);
|
||||
ea.destroy();
|
||||
} else {
|
||||
const modal = new UniversalInsertFileModal(this.plugin, this);
|
||||
modal.open(file, this.currentPosition);
|
||||
if(link.match(/^[^#]*#page=\d*(&\w*=[^&]+){0,}&rect=\d*,\d*,\d*,\d*/g)) {
|
||||
const ea = getEA(this) as ExcalidrawAutomate;
|
||||
await ea.addImage(this.currentPosition.x, this.currentPosition.y,link);
|
||||
ea.addElementsToView(false,false).then(()=>ea.destroy());
|
||||
} else {
|
||||
const modal = new UniversalInsertFileModal(this.plugin, this);
|
||||
modal.open(file, this.currentPosition);
|
||||
}
|
||||
}
|
||||
this.setDirty(9);
|
||||
})) {
|
||||
|
||||
@@ -42,7 +42,7 @@ let plugin: ExcalidrawPlugin;
|
||||
let app: App;
|
||||
let vault: Vault;
|
||||
let metadataCache: MetadataCache;
|
||||
const DEBUGGING_MPP = true;
|
||||
const DEBUGGING_MPP = false;
|
||||
|
||||
|
||||
const getDefaultWidth = (plugin: ExcalidrawPlugin): string => {
|
||||
@@ -623,6 +623,9 @@ const isTextOnlyEmbed = (internalEmbedEl: Element):boolean => {
|
||||
const tmpObsidianWYSIWYG = async (
|
||||
el: HTMLElement,
|
||||
ctx: MarkdownPostProcessorContext,
|
||||
isPrinting: boolean,
|
||||
isMarkdownReadingMode: boolean,
|
||||
isHoverPopover: boolean,
|
||||
) => {
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING_MPP && debug(tmpObsidianWYSIWYG, `MarkdownPostProcessor.ts > tmpObsidianWYSIWYG`);
|
||||
const file = app.vault.getAbstractFileByPath(ctx.sourcePath);
|
||||
@@ -642,11 +645,11 @@ const tmpObsidianWYSIWYG = async (
|
||||
//@ts-ignore
|
||||
const containerEl = ctx.containerEl;
|
||||
|
||||
if(!plugin.settings.renderImageInMarkdownReadingMode && containerEl.parentElement?.parentElement?.hasClass("markdown-reading-view")) {
|
||||
if(!plugin.settings.renderImageInMarkdownReadingMode && isMarkdownReadingMode) { // containerEl.parentElement?.parentElement?.hasClass("markdown-reading-view")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!plugin.settings.renderImageInMarkdownToPDF && containerEl.parentElement?.hasClass("print")) {
|
||||
if(!plugin.settings.renderImageInMarkdownToPDF && isPrinting) { //containerEl.parentElement?.hasClass("print")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -674,14 +677,14 @@ const tmpObsidianWYSIWYG = async (
|
||||
|
||||
|
||||
if(!plugin.settings.renderImageInHoverPreviewForMDNotes) {
|
||||
const isHoverPopover = internalEmbedDiv.parentElement?.hasClass("hover-popover");
|
||||
//const isHoverPopover = internalEmbedDiv.parentElement?.hasClass("hover-popover");
|
||||
const shouldOpenMD = Boolean(ctx.frontmatter?.["excalidraw-open-md"]);
|
||||
if(isHoverPopover && shouldOpenMD) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const isPrinting = Boolean(internalEmbedDiv.hasClass("print"));
|
||||
//const isPrinting = Boolean(internalEmbedDiv.hasClass("print"));
|
||||
|
||||
const attr: imgElementAttributes = {
|
||||
fname: ctx.sourcePath,
|
||||
@@ -693,7 +696,7 @@ const tmpObsidianWYSIWYG = async (
|
||||
attr.file = file;
|
||||
|
||||
const markdownEmbed = internalEmbedDiv.hasClass("markdown-embed");
|
||||
const markdownReadingView = internalEmbedDiv.hasClass("markdown-reading-view") || isPrinting;
|
||||
const markdownReadingView = isPrinting || isMarkdownReadingMode; //internalEmbedDiv.hasClass("markdown-reading-view")
|
||||
if (!internalEmbedDiv.hasClass("internal-embed") && (markdownEmbed || markdownReadingView)) {
|
||||
if(isPrinting) {
|
||||
internalEmbedDiv = containerEl;
|
||||
@@ -790,16 +793,22 @@ export const markdownPostProcessor = async (
|
||||
el: HTMLElement,
|
||||
ctx: MarkdownPostProcessorContext,
|
||||
) => {
|
||||
const isPrinting = Boolean(document.body.querySelectorAll("body > .print").length>0);
|
||||
if(isPrinting && el.hasClass("mod-frontmatter")) {
|
||||
return;
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
const containerEl = ctx.containerEl;
|
||||
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING_MPP && debug(markdownPostProcessor, `MarkdownPostProcessor.ts > markdownPostProcessor`, ctx, el);
|
||||
|
||||
//check to see if we are rendering in editing mode or live preview
|
||||
//if yes, then there should be no .internal-embed containers
|
||||
const isPrinting = Boolean(document.body.querySelectorAll("body > .print").length>0);
|
||||
const isPreview = isPrinting ||
|
||||
//@ts-ignore
|
||||
Boolean(ctx.containerEl && getParentOfClass(ctx.containerEl, "markdown-reading-view")) ||
|
||||
//@ts-ignore
|
||||
(Boolean(ctx.containerEl && getParentOfClass(ctx.containerEl, "hover-popover")) &&
|
||||
Boolean(ctx?.frontmatter?.["excalidraw-open-md"])) ;
|
||||
const isMarkdownReadingMode = Boolean(containerEl && getParentOfClass(containerEl, "markdown-reading-view"));
|
||||
const isHoverPopover = Boolean(containerEl && getParentOfClass(containerEl, "hover-popover"));
|
||||
const isPreview = isPrinting || isMarkdownReadingMode ||
|
||||
(isHoverPopover && Boolean(ctx?.frontmatter?.["excalidraw-open-md"]) && !plugin.settings.renderImageInHoverPreviewForMDNotes);
|
||||
const embeddedItems = el.querySelectorAll(".internal-embed");
|
||||
if (!isPreview && embeddedItems.length === 0) {
|
||||
if(el.hasClass("mod-frontmatter")) {
|
||||
@@ -812,7 +821,7 @@ export const markdownPostProcessor = async (
|
||||
return;
|
||||
}
|
||||
}
|
||||
await tmpObsidianWYSIWYG(el, ctx);
|
||||
await tmpObsidianWYSIWYG(el, ctx, isPrinting, isMarkdownReadingMode, isHoverPopover);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -826,9 +835,6 @@ export const markdownPostProcessor = async (
|
||||
return;
|
||||
}
|
||||
|
||||
if(isPrinting && el.hasClass("mod-frontmatter")) {
|
||||
return;
|
||||
}
|
||||
await processReadingMode(embeddedItems, ctx);
|
||||
};
|
||||
|
||||
|
||||
@@ -322,6 +322,7 @@ FILENAME_HEAD: "Filename",
|
||||
DEFAULT_PEN_MODE_NAME: "Pen mode",
|
||||
DEFAULT_PEN_MODE_DESC:
|
||||
"Should pen mode be automatically enabled when opening Excalidraw?",
|
||||
DISABLE_DOUBLE_TAP_ERASER_NAME: "Enable double-tap eraser in pen mode",
|
||||
SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_NAME: "Show (+) crosshair in pen mode",
|
||||
SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_DESC:
|
||||
"Show crosshair in pen mode when using the freedraw tool. <b><u>Toggle ON:</u></b> SHOW <b><u>Toggle OFF:</u></b> HIDE<br>"+
|
||||
@@ -331,18 +332,18 @@ FILENAME_HEAD: "Filename",
|
||||
"...even if the file has the <b>excalidraw-open-md: true</b> frontmatter key.<br>" +
|
||||
"When this setting is off and the file is set to open in md by default, the hover preview will show the " +
|
||||
"markdown side of the document.",
|
||||
SHOW_DRAWING_OR_MD_IN_READING_MODE_NAME: "Render image when in markdown reading mode",
|
||||
SHOW_DRAWING_OR_MD_IN_READING_MODE_NAME: "Render as image when in markdown reading mode of an Excalidraw file",
|
||||
SHOW_DRAWING_OR_MD_IN_READING_MODE_DESC:
|
||||
"Must close the active excalidraw/markdown file and reopen it for this change to take effect.<br>When you are in markdown reading mode (aka. reading the back side of the drawing), should the Excalidraw drawing be rendered as an image? " +
|
||||
"This setting will not affect the display of the drawing when you are in Excalidraw mode, when you embed the drawing into a markdown document or when rendering hover preview.<br><ul>" +
|
||||
"<li>See other related setting for <b>PDF Export</b> under 'Embedding and Exporting' further below.</li>" +
|
||||
"<li>Be sure to check out the <b>Fade Out setting</b> in the 'Miscellaneous fetures' section.</li></ul>",
|
||||
SHOW_DRAWING_OR_MD_IN_EXPORTPDF_NAME: "Render Excalidraw as an image when EXPORTING TO PDF",
|
||||
"When you are in markdown reading mode (aka. reading the back side of the drawing) should the Excalidraw drawing be rendered as an image? " +
|
||||
"This setting will not affect the display of the drawing when you are in Excalidraw mode or when you embed the drawing into a markdown document or when rendering hover preview.<br><ul>" +
|
||||
"<li>See other related setting for <b>PDF Export</b> under 'Embedding and Exporting' further below.</li></ul><br>" +
|
||||
"You must close the active excalidraw/markdown file and reopen it for this change to take effect.",
|
||||
SHOW_DRAWING_OR_MD_IN_EXPORTPDF_NAME: "Render the file as an image when exporting an Excalidraw file to PDF",
|
||||
SHOW_DRAWING_OR_MD_IN_EXPORTPDF_DESC:
|
||||
"This setting controls the behavior of Excalidraw when exporting a file to PDF in markdown mode using Obsidian's Export to PDF... feature.<br>" +
|
||||
"When <b>enabled</b> the PDF will show the Excalidraw drawing only; when <b>disabled</b> the PDF will show the markdown side of the document.<br><ul>" +
|
||||
"<li>See other related setting for <b>Markdown Reading Mode</b> under 'Appearnace and Behavior' further above.</li>" +
|
||||
"<li>Be sure to check out the <b>Fade Out setting</b> in the 'Miscellaneous fetures' section.</li></ul><br>" +
|
||||
"This setting controls the behavior of Excalidraw when exporting an Excalidraw file to PDF in markdown view mode using Obsidian's <b>Export to PDF</b> feature.<br>" +
|
||||
"<ul><li>When <b>enabled</b> the PDF will show the Excalidraw drawing only;</li>" +
|
||||
"<li>When <b>disabled</b> the PDF will show the markdown side of the document.</li></ul>" +
|
||||
"See the other related setting for <b>Markdown Reading Mode</b> under 'Appearnace and Behavior' further above.<br>" +
|
||||
"⚠️ Note, you must close the active excalidraw/markdown file and reopen for this change to take effect. ⚠️",
|
||||
THEME_HEAD: "Theme and styling",
|
||||
ZOOM_HEAD: "Zoom",
|
||||
|
||||
@@ -78,6 +78,7 @@ export interface ExcalidrawSettings {
|
||||
matchThemeTrigger: boolean;
|
||||
defaultMode: string;
|
||||
defaultPenMode: "never" | "mobile" | "always";
|
||||
penModeDoubleTapEraser: boolean;
|
||||
penModeCrosshairVisible: boolean;
|
||||
renderImageInMarkdownReadingMode: boolean,
|
||||
renderImageInHoverPreviewForMDNotes: boolean,
|
||||
@@ -244,6 +245,7 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
|
||||
matchThemeTrigger: false,
|
||||
defaultMode: "normal",
|
||||
defaultPenMode: "never",
|
||||
penModeDoubleTapEraser: true,
|
||||
penModeCrosshairVisible: true,
|
||||
renderImageInMarkdownReadingMode: false,
|
||||
renderImageInHoverPreviewForMDNotes: false,
|
||||
@@ -1026,6 +1028,17 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(detailsEl)
|
||||
.setName(t("DISABLE_DOUBLE_TAP_ERASER_NAME"))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.penModeDoubleTapEraser)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.penModeDoubleTapEraser = value;
|
||||
this.applySettingsUpdate();
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(detailsEl)
|
||||
.setName(t("SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_NAME"))
|
||||
.setDesc(fragWithHTML(t("SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_DESC")))
|
||||
|
||||
@@ -922,3 +922,20 @@ export async function getFontMetrics(fontUrl: string, name: string): Promise<Fon
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Thanks https://stackoverflow.com/a/54555834
|
||||
export function cropCanvas(
|
||||
srcCanvas: HTMLCanvasElement,
|
||||
crop: { left: number, top: number, width: number, height: number },
|
||||
output: { width: number, height: number } = { width: crop.width, height: crop.height })
|
||||
{
|
||||
const dstCanvas = createEl('canvas');
|
||||
dstCanvas.width = output.width;
|
||||
dstCanvas.height = output.height;
|
||||
dstCanvas.getContext('2d')!.drawImage(
|
||||
srcCanvas,
|
||||
crop.left, crop.top, crop.width, crop.height,
|
||||
0, 0, output.width, output.height
|
||||
);
|
||||
return dstCanvas;
|
||||
}
|
||||
Reference in New Issue
Block a user