diff --git a/package.json b/package.json
index ffffc99..4ad072e 100644
--- a/package.json
+++ b/package.json
@@ -23,7 +23,7 @@
"license": "MIT",
"dependencies": {
"@popperjs/core": "^2.11.8",
- "@zsviczian/excalidraw": "0.18.0-8",
+ "@zsviczian/excalidraw": "0.18.0-9",
"chroma-js": "^2.4.2",
"clsx": "^2.0.0",
"@zsviczian/colormaster": "^1.2.2",
diff --git a/src/core/settings.ts b/src/core/settings.ts
index 4c3a550..666e308 100644
--- a/src/core/settings.ts
+++ b/src/core/settings.ts
@@ -46,6 +46,7 @@ import { PDFExportSettingsComponent, PDFExportSettings } from "src/shared/Dialog
import de from "src/lang/locale/de";
export interface ExcalidrawSettings {
+ disableDoubleClickTextEditing: boolean;
folder: string;
cropFolder: string;
annotateFolder: string;
@@ -228,6 +229,7 @@ export interface ExcalidrawSettings {
declare const PLUGIN_VERSION:string;
export const DEFAULT_SETTINGS: ExcalidrawSettings = {
+ disableDoubleClickTextEditing: false,
folder: "Excalidraw",
cropFolder: "",
annotateFolder: "",
@@ -684,6 +686,17 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
}),
);
+ new Setting(detailsEl)
+ .setName(t("TOGGLE_SPLASHSCREEN"))
+ .addToggle((toggle) =>
+ toggle
+ .setValue(this.plugin.settings.showSplashscreen)
+ .onChange((value)=> {
+ this.plugin.settings.showSplashscreen = value;
+ this.applySettingsUpdate();
+ })
+ )
+
new Setting(detailsEl)
.setName(t("FOLDER_NAME"))
.setDesc(fragWithHTML(t("FOLDER_DESC")))
@@ -1094,6 +1107,17 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
cls: "excalidraw-setting-h1",
});
+ new Setting(detailsEl)
+ .setName(t("ENABLE_DOUBLE_CLICK_TEXT_EDITING_NAME"))
+ .addToggle((toggle) =>
+ toggle
+ .setValue(!this.plugin.settings.disableDoubleClickTextEditing)
+ .onChange(async (value) => {
+ this.plugin.settings.disableDoubleClickTextEditing = !value;
+ this.applySettingsUpdate();
+ }),
+ );
+
const readingModeEl = new Setting(detailsEl)
.setName(t("SHOW_DRAWING_OR_MD_IN_READING_MODE_NAME"))
.setDesc(fragWithHTML(t("SHOW_DRAWING_OR_MD_IN_READING_MODE_DESC")))
@@ -1136,17 +1160,6 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
);
addIframe(detailsEl, "H8Njp7ZXYag",999);
- new Setting(detailsEl)
- .setName(t("TOGGLE_SPLASHSCREEN"))
- .addToggle((toggle) =>
- toggle
- .setValue(this.plugin.settings.showSplashscreen)
- .onChange((value)=> {
- this.plugin.settings.showSplashscreen = value;
- this.applySettingsUpdate();
- })
- )
-
detailsEl = displayDetailsEl.createEl("details");
detailsEl.createEl("summary", {
text: t("HOTKEY_OVERRIDE_HEAD"),
diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts
index 2607d00..9d4070a 100644
--- a/src/lang/locale/en.ts
+++ b/src/lang/locale/en.ts
@@ -371,6 +371,7 @@ FILENAME_HEAD: "Filename",
DEFAULT_PEN_MODE_NAME: "Pen mode",
DEFAULT_PEN_MODE_DESC:
"Should pen mode be automatically enabled when opening Excalidraw?",
+ ENABLE_DOUBLE_CLICK_TEXT_EDITING_NAME: "Enable double-click text create",
DISABLE_DOUBLE_TAP_ERASER_NAME: "Enable double-tap eraser in pen mode",
DISABLE_SINGLE_FINGER_PANNING_NAME: "Enable single-finger panning in pen mode",
SHOW_PEN_MODE_FREEDRAW_CROSSHAIR_NAME: "Show (+) crosshair in pen mode",
diff --git a/src/shared/Dialogs/ExportDialog.ts b/src/shared/Dialogs/ExportDialog.ts
index a4f5f31..52a6d7b 100644
--- a/src/shared/Dialogs/ExportDialog.ts
+++ b/src/shared/Dialogs/ExportDialog.ts
@@ -43,6 +43,7 @@ export class ExportDialog extends Modal {
public customPaperColor: string = "#ffffff";
public alignment: PDFPageAlignment = "center";
public margin: PDFPageMarginString = "normal";
+ private scaleSetting:Setting;
constructor(
private plugin: ExcalidrawPlugin,
@@ -85,6 +86,17 @@ export class ExportDialog extends Modal {
this.selectedOnlySetting = null;
this.containerEl.remove();
}
+
+ updateBoundingBox() {
+ if(this.hasSelectedElements && this.exportSelectedOnly) {
+ this.boundingBox = this.ea.getBoundingBox(this.view.getViewSelectedElements());
+ } else {
+ this.boundingBox = this.ea.getBoundingBox(this.ea.getViewElements());
+ }
+ if(this.scaleSetting) {
+ this.scaleSetting.setDesc(this.size());
+ }
+ }
onOpen(): void {
this.containerEl.classList.add("excalidraw-release");
@@ -92,6 +104,7 @@ export class ExportDialog extends Modal {
this.hasSelectedElements = this.view.getViewSelectedElements().length > 0;
//@ts-ignore
this.selectedOnlySetting.setVisibility(this.hasSelectedElements);
+ this.updateBoundingBox();
}
async onClose() {
@@ -167,9 +180,14 @@ export class ExportDialog extends Modal {
this.createPDFButton();
}
}
+
+ private size ():DocumentFragment {
+ const width = Math.round(this.scale*this.boundingBox.width + this.padding*2);
+ const height = Math.round(this.scale*this.boundingBox.height + this.padding*2);
+ return fragWithHTML(`${t("EXPORTDIALOG_SIZE_DESC")}
${t("EXPORTDIALOG_SCALE_VALUE")} ${this.scale}
${t("EXPORTDIALOG_IMAGE_SIZE")} ${width}x${height}`);
+ }
private createImageSettings() {
- let scaleSetting:Setting;
let paddingSetting: Setting;
this.contentContainer.createEl("h1",{text: t("EXPORTDIALOG_IMAGE_SETTINGS")});
@@ -177,12 +195,6 @@ export class ExportDialog extends Modal {
this.createSaveSettingsDropdown();
- const size = ():DocumentFragment => {
- const width = Math.round(this.scale*this.boundingBox.width + this.padding*2);
- const height = Math.round(this.scale*this.boundingBox.height + this.padding*2);
- return fragWithHTML(`${t("EXPORTDIALOG_SIZE_DESC")}
${t("EXPORTDIALOG_SCALE_VALUE")} ${this.scale}
${t("EXPORTDIALOG_IMAGE_SIZE")} ${width}x${height}`);
- }
-
const padding = ():DocumentFragment => {
return fragWithHTML(`${t("EXPORTDIALOG_CURRENT_PADDING")} ${this.padding}`);
}
@@ -196,21 +208,21 @@ export class ExportDialog extends Modal {
.setValue(this.padding)
.onChange(value => {
this.padding = value;
- scaleSetting.setDesc(size());
+ this.scaleSetting.setDesc(this.size());
paddingSetting.setDesc(padding());
})
})
- scaleSetting = new Setting(this.contentContainer)
+ this.scaleSetting = new Setting(this.contentContainer)
.setName(t("EXPORTDIALOG_SCALE"))
- .setDesc(size())
+ .setDesc(this.size())
.addSlider(slider =>
slider
.setLimits(0.2,7,0.1)
.setValue(this.scale)
.onChange(value => {
this.scale = value;
- scaleSetting.setDesc(size());
+ this.scaleSetting.setDesc(this.size());
})
)
@@ -247,6 +259,7 @@ export class ExportDialog extends Modal {
.setValue(this.exportSelectedOnly?"selected":"all")
.onChange(value => {
this.exportSelectedOnly = value === "selected";
+ this.updateBoundingBox();
})
);
}
diff --git a/src/shared/Dialogs/InsertPDFModal.ts b/src/shared/Dialogs/InsertPDFModal.ts
index d2f024f..13f1826 100644
--- a/src/shared/Dialogs/InsertPDFModal.ts
+++ b/src/shared/Dialogs/InsertPDFModal.ts
@@ -70,7 +70,7 @@ export class InsertPDFModal extends Modal {
this.setImageSizeMessage = null;
}
- private async getPageDimensions (pdfDoc: any) {
+ private async getPDFPageDimensions (pdfDoc: any) {
try {
const scale = this.plugin.settings.pdfScale;
const canvas = createEl("canvas");
@@ -197,7 +197,7 @@ export class InsertPDFModal extends Modal {
rangeOnChange(`1-${numPages}`);
importButtonMessages();
numPagesMessages();
- this.getPageDimensions(this.pdfDoc);
+ this.getPDFPageDimensions(this.pdfDoc);
} else {
importButton.setDisabled(true);
}
diff --git a/src/shared/Dialogs/Messages.ts b/src/shared/Dialogs/Messages.ts
index 02968e9..5eca86c 100644
--- a/src/shared/Dialogs/Messages.ts
+++ b/src/shared/Dialogs/Messages.ts
@@ -23,6 +23,8 @@ I build this plugin in my free time, as a labor of love. Curious about the philo
## New
- Expose parameter in plugin settings to disable AI functionality [#2325](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2325)
+- Enable double-click text editing option in Excalidraw appearance and behavior (based on request on Discord)
+- Added two new PDF export sizes: "Match image", "HD Screen".
## Fixed in the plugin
- Scaling multiple embeddables at once did not work. [#2276](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2276)
diff --git a/src/shared/Dialogs/PDFExportSettingsComponent.ts b/src/shared/Dialogs/PDFExportSettingsComponent.ts
index 2c2f833..7a9463d 100644
--- a/src/shared/Dialogs/PDFExportSettingsComponent.ts
+++ b/src/shared/Dialogs/PDFExportSettingsComponent.ts
@@ -21,6 +21,10 @@ export class PDFExportSettingsComponent {
if (!update) this.update = () => {};
}
+ isOrientationAndTilingVisible() {
+ return !(this.settings.pageSize === "HD Screen" || this.settings.pageSize === "MATCH IMAGE");
+ }
+
render() {
const pageSizeOptions: Record = Object.keys(STANDARD_PAGE_SIZES)
.reduce((acc, key) => ({
@@ -28,6 +32,8 @@ export class PDFExportSettingsComponent {
[key]: key
}), {});
+ let div: HTMLDivElement;
+
new Setting(this.contentEl)
.setName(t("EXPORTDIALOG_PAGE_SIZE"))
.addDropdown(dropdown =>
@@ -36,11 +42,15 @@ export class PDFExportSettingsComponent {
.setValue(this.settings.pageSize)
.onChange(value => {
this.settings.pageSize = value as PageSize;
+ div.style.display = this.isOrientationAndTilingVisible() ? "block" : "none";
this.update();
})
);
- new Setting(this.contentEl)
+ div = this.contentEl.createDiv();
+ div.style.display = this.isOrientationAndTilingVisible() ? "block" : "none";
+
+ new Setting(div)
.setName(t("EXPORTDIALOG_PAGE_ORIENTATION"))
.addDropdown(dropdown =>
dropdown
@@ -55,7 +65,7 @@ export class PDFExportSettingsComponent {
})
);
- new Setting(this.contentEl)
+ new Setting(div)
.setName(t("EXPORTDIALOG_PDF_FIT_TO_PAGE"))
.addDropdown(dropdown =>
dropdown
diff --git a/src/utils/exportUtils.ts b/src/utils/exportUtils.ts
index ae40297..f421f00 100644
--- a/src/utils/exportUtils.ts
+++ b/src/utils/exportUtils.ts
@@ -54,7 +54,9 @@ export const STANDARD_PAGE_SIZES = {
Legal: { width: 816, height: 1344 }, // 8.5 × 14 inches
Letter: { width: 816, height: 1056 }, // 8.5 × 11 inches
Tabloid: { width: 1056, height: 1632 }, // 11 × 17 inches
- Ledger: { width: 1632, height: 1056 } // 17 × 11 inches
+ Ledger: { width: 1632, height: 1056 }, // 17 × 11 inches
+ "HD Screen": { width: 1920, height: 1080 },// 16:9 aspect ratio
+ "MATCH IMAGE": { width: 0, height: 0 }, // 0 means use the current screen size
} as const;
export type PageSize = keyof typeof STANDARD_PAGE_SIZES;
@@ -69,9 +71,15 @@ export function getMarginValue(margin:PDFPageMarginString): PDFMargin {
}
}
-export function getPageDimensions(pageSize: PageSize, orientation: PageOrientation): PageDimensions {
- const dimensions = STANDARD_PAGE_SIZES[pageSize];
- return orientation === "portrait"
+export function getPageDimensions(pageSize: PageSize, orientation: PageOrientation, dims?: {width: number, height: number}): PageDimensions {
+ let dimensions:{width: number, height: number};
+ dimensions = STANDARD_PAGE_SIZES[pageSize];
+
+ if (dims && dimensions.width === 0 && dimensions.height === 0) {
+ dimensions = { width: dims.width, height: dims.height };
+ }
+
+ return orientation === "portrait" || pageSize === "MATCH IMAGE" || pageSize === "HD Screen"
? { width: dimensions.width, height: dimensions.height }
: { width: dimensions.height, height: dimensions.width };
}
diff --git a/src/view/ExcalidrawView.ts b/src/view/ExcalidrawView.ts
index 78ee4f4..c0895c1 100644
--- a/src/view/ExcalidrawView.ts
+++ b/src/view/ExcalidrawView.ts
@@ -77,7 +77,6 @@ import {
getExcalidrawMarkdownHeaderSection,
} from "../shared/ExcalidrawData";
import {
- arrayBufferToBase64,
checkAndCreateFolder,
createOrOverwriteFile,
download,
@@ -155,7 +154,6 @@ import { ImageInfo } from "src/types/excalidrawAutomateTypes";
import { exportToPDF, getMarginValue, getPageDimensions, PageOrientation, PageSize } from "src/utils/exportUtils";
import { FrameRenderingOptions } from "src/types/utilTypes";
import { CaptureUpdateAction } from "src/constants/constants";
-import { FlipHorizontal } from "lucide-react";
const EMBEDDABLE_SEMAPHORE_TIMEOUT = 2000;
const PREVENT_RELOAD_TIMEOUT = 2000;
@@ -612,8 +610,10 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
return;
}
+ const scene = this.getScene(selectedOnly);
+
const svg = await this.svg(
- this.getScene(selectedOnly),
+ scene,
undefined,
false,
true
@@ -622,20 +622,26 @@ export default class ExcalidrawView extends TextFileView implements HoverParent{
if (!svg) {
return;
}
-
+
+ const boundingBox = this.plugin.ea.getBoundingBox(scene.elements);
+ const margin = getMarginValue(this.exportDialog.margin);
+ const [width, height] = [boundingBox.width, boundingBox.height];
+
exportToPDF({
SVG: [svg],
scale: {
zoom: this.exportDialog.scale,
- fitToPage: this.exportDialog.fitToPage
+ fitToPage: pageSize === "MATCH IMAGE" || pageSize === "HD Screen"
+ ? 1
+ : this.exportDialog.fitToPage
},
pageProps: {
- dimensions: getPageDimensions(pageSize, orientation),
+ dimensions: getPageDimensions(pageSize, orientation, {width, height}),
backgroundColor: this.exportDialog.getPaperColor(),
- margin: getMarginValue(this.exportDialog.margin),
+ margin,
alignment: this.exportDialog.alignment,
},
- filename: this.file.basename,
+ filename: this.file.basename+".pdf",
});
}