Persist pan & zoom in state

This commit is contained in:
Sidharth Vinod
2022-08-12 22:15:36 +05:30
parent 4441102c66
commit 1bc0718901
5 changed files with 50 additions and 26 deletions
+2 -1
View File
@@ -97,7 +97,8 @@
const loadSampleDiagram = (diagramType: string): void => {
updateCode(samples[diagramType], {
updateDiagram: true,
updateEditor: true
updateEditor: true,
resetPanZoom: true
});
};
</script>
+35 -22
View File
@@ -1,5 +1,5 @@
<script lang="ts">
import { inputStateStore, stateStore } from '$lib/util/state';
import { inputStateStore, stateStore, updateCodeStore } from '$lib/util/state';
import { onMount } from 'svelte';
import mermaid from 'mermaid';
import panzoom from 'svg-pan-zoom';
@@ -12,9 +12,18 @@
let outOfSync = false;
let hide = false;
let manualUpdate = true;
let pan: SvgPanZoom.Point;
let zoom: number;
let pzoom: SvgPanZoom.Instance;
let debounce: number;
const handlePanZoomChange = () => {
const pan = pzoom.getPan();
const zoom = pzoom.getZoom();
clearTimeout(debounce);
debounce = window.setTimeout(() => {
updateCodeStore({ pan, zoom });
}, 500);
};
onMount(() => {
stateStore.subscribe((state) => {
if (state.error !== undefined) {
@@ -40,28 +49,25 @@
mermaid.initialize(Object.assign({}, JSON.parse(state.mermaid)));
mermaid.render('graph-div', code, (svgCode) => {
if (svgCode.length > 0) {
let oldPan = pan ? { ...pan } : undefined;
let oldZoom = zoom;
pzoom?.destroy();
pzoom = undefined;
hide = true;
container.innerHTML = svgCode;
setTimeout(() => {
pzoom = panzoom('#graph-div', {
onPan: (p) => {
pan = p;
zoom = pzoom.getZoom();
},
onZoom: (z) => {
zoom = z;
pan = pzoom.getPan();
},
zoomEnabled: true,
panEnabled: true,
controlIconsEnabled: true
const graphDiv = document.getElementById('graph-div');
graphDiv.setAttribute('height', '100%');
graphDiv.style.maxWidth = '100%';
pzoom = panzoom(graphDiv, {
onPan: handlePanZoomChange,
onZoom: handlePanZoomChange,
controlIconsEnabled: true,
fit: true,
center: true
});
if (oldPan !== undefined && oldZoom !== undefined) {
pzoom.zoom(oldZoom);
pzoom.pan(oldPan);
const { pan, zoom } = state;
if (pan !== undefined && zoom !== undefined) {
pzoom.zoom(zoom);
pzoom.pan(pan);
}
hide = false;
}, 0);
@@ -79,6 +85,13 @@
error = true;
}
});
window.addEventListener('resize', () => {
if (pzoom) {
pzoom.resize();
pzoom.fit();
pzoom.center();
}
});
});
</script>
@@ -86,8 +99,8 @@
<div class="p-2 text-red-600" id="errorContainer">{$stateStore.error}</div>
{/if}
<div id="view" bind:this={view} class="p-2" class:error class:outOfSync>
<div id="container" bind:this={container} class="flex-1 overflow-auto" class:hide />
<div id="view" bind:this={view} class="p-2 h-full" class:error class:outOfSync>
<div id="container" bind:this={container} class="h-full overflow-auto" class:hide />
</div>
<style>
+2
View File
@@ -39,6 +39,8 @@ export interface State {
updateEditor: boolean;
updateDiagram: boolean;
autoSync: boolean;
pan?: { x: number; y: number };
zoom?: number;
loader?: LoaderConfig;
}
+9 -1
View File
@@ -114,7 +114,11 @@ export const updateCodeStore = (newState: Partial<State>): void => {
let prompted = false;
export const updateCode = (
code: string,
{ updateEditor, updateDiagram = false }: { updateEditor: boolean; updateDiagram?: boolean }
{
updateEditor,
updateDiagram = false,
resetPanZoom = false
}: { updateEditor: boolean; updateDiagram?: boolean; resetPanZoom?: boolean }
): void => {
saveStatistics(code);
const lines = (code.match(/\n/g) || '').length + 1;
@@ -132,6 +136,10 @@ export const updateCode = (
}
inputStateStore.update((state) => {
if (resetPanZoom) {
state.pan = undefined;
state.zoom = undefined;
}
return { ...state, code, updateEditor, updateDiagram };
});
};
+2 -2
View File
@@ -93,10 +93,10 @@
}
];
let debounce: { [key: string]: any } = {};
let debounce: { [key: string]: number } = {};
const updateHandler = (message: CustomEvent<EditorUpdateEvent>) => {
clearTimeout(debounce[selectedMode]);
debounce[selectedMode] = setTimeout(() => {
debounce[selectedMode] = window.setTimeout(() => {
const code = message.detail.text;
if (selectedMode === 'code') {
updateCode(code, {