Add option to remember editor position and zoom

This commit is contained in:
MassiveBox 2025-05-06 18:19:18 +02:00
parent fa3eba219e
commit 764f9fe5a4
Signed by: massivebox
GPG key ID: 9B74D3A59181947D
3 changed files with 50 additions and 4 deletions

View file

@ -35,6 +35,10 @@
"analytics": {
"title": "Analytics",
"description": "Enable to send anonymous usage data to the developer. <a href='https://s.massive.box/jsdraw-plugin-privacy'>Privacy Policy</a>"
},
"restorePosition": {
"title": "Remember editor position",
"description": "When enabled, the editor will remember the zoom factor and position, and it will restore them the next time you open the drawing."
}
}
}

View file

@ -4,6 +4,7 @@ import {Plugin, showMessage} from "siyuan";
import {SettingUtils} from "@/libs/setting-utils";
type Options = {
restorePosition: boolean;
grid: boolean
background: string
dialogOnDesktop: boolean
@ -11,6 +12,7 @@ type Options = {
};
export type DefaultEditorOptions = {
restorePosition: boolean;
grid: boolean
background: string
}
@ -30,8 +32,9 @@ export class PluginConfig {
getDefaultEditorOptions(): DefaultEditorOptions {
return {
restorePosition: this.options.restorePosition,
grid: this.options.grid,
background: this.options.background,
background: this.options.background
};
}
@ -50,6 +53,7 @@ export class PluginConfig {
background: "#00000000",
dialogOnDesktop: false,
analytics: true,
restorePosition: true,
};
this.firstRun = true;
}
@ -107,6 +111,7 @@ export class PluginConfigViewer {
background: color,
dialogOnDesktop: data.dialogOnDesktop,
analytics: data.analytics,
restorePosition: data.restorePosition,
});
await this.config.save();
@ -148,6 +153,14 @@ export class PluginConfigViewer {
type: 'textinput',
});
this.settingUtils.addItem({
key: "restorePosition",
title: this.plugin.i18n.settings.restorePosition.title,
description: this.plugin.i18n.settings.restorePosition.description,
value: this.config.options.restorePosition,
type: 'checkbox'
});
this.settingUtils.addItem({
key: "dialogOnDesktop",
title: this.plugin.i18n.settings.dialogOnDesktop.title,

View file

@ -1,7 +1,15 @@
import {MaterialIconProvider} from "@js-draw/material-icons";
import {PluginAsset, PluginFile} from "@/file";
import {JSON_MIME, STORAGE_PATH, SVG_MIME, TOOLBAR_FILENAME} from "@/const";
import Editor, {BackgroundComponentBackgroundType, BaseWidget, Color4, EditorEventType} from "js-draw";
import Editor, {
BackgroundComponentBackgroundType,
BaseWidget,
Color4,
EditorEventType,
Mat33,
Vec2,
Viewport
} from "js-draw";
import {Dialog, getFrontend, openTab, Plugin, showMessage} from "siyuan";
import {findSyncIDInProtyle, replaceSyncID} from "@/protyle";
import DrawJSPlugin from "@/index";
@ -62,9 +70,26 @@ export class PluginEditor {
this.drawingFile = new PluginAsset(this.fileID, this.syncID, SVG_MIME);
await this.drawingFile.loadFromSiYuanFS();
const drawingContent = this.drawingFile.getContent();
if(drawingContent != null) {
await this.editor.loadFromSVG(drawingContent);
// restore position and zoom
const svgElem = new DOMParser().parseFromString(drawingContent, SVG_MIME).documentElement;
const editorViewStr = svgElem.getAttribute('editorView');
if(editorViewStr != null && defaultEditorOptions.restorePosition) {
try {
const [viewBoxOriginX, viewBoxOriginY, zoom] = editorViewStr.split(' ').map(x => parseFloat(x));
this.editor.dispatch(Viewport.transformBy(Mat33.scaling2D(zoom)));
this.editor.dispatch(Viewport.transformBy(Mat33.translation(Vec2.of(
- viewBoxOriginX,
- viewBoxOriginY
))));
}catch (e){}
}
if(this.drawingFile.getContent() != null) {
await this.editor.loadFromSVG(this.drawingFile.getContent());
}else{
// it's a new drawing
this.editor.dispatch(this.editor.setBackgroundStyle({
@ -106,6 +131,10 @@ export class PluginEditor {
let newSyncID: string;
const oldSyncID = this.syncID;
const rect = this.editor.viewport.visibleRect;
const zoom = this.editor.viewport.getScaleFactor();
svgElem.setAttribute('editorView', `${rect.x} ${rect.y} ${zoom}`)
try {
this.drawingFile.setContent(svgElem.outerHTML);
await this.drawingFile.save();