diff options
-rw-r--r-- | html/merfolk/app.js | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/html/merfolk/app.js b/html/merfolk/app.js index 851e426..cb6eccf 100644 --- a/html/merfolk/app.js +++ b/html/merfolk/app.js @@ -1,6 +1,11 @@ /** * Mermaid diagram editor and viewer application - * Provides real-time preview, pan/zoom functionality, and export capabilities + * Features: + * - Real-time preview of Mermaid diagrams + * - Pan and zoom functionality + * - Export as PNG with configurable scale + * - Export as SVG + * - Reset view to center */ // Configuration @@ -22,7 +27,7 @@ const resetBtn = document.getElementById('reset-btn'); let panzoomInstance = null; /** - * Creates a debounced version of a function + * Creates a debounced version of a function to prevent too many renders * @param {Function} func - The function to debounce * @param {number} wait - The number of milliseconds to delay * @returns {Function} Debounced function @@ -41,6 +46,7 @@ const debounce = (func, wait) => { /** * Renders a Mermaid diagram from the provided text + * Handles initialization of panzoom functionality * @param {string} text - The Mermaid diagram syntax * @returns {Promise<void>} */ @@ -79,7 +85,18 @@ const renderMermaid = async (text) => { }; /** + * Resets the pan/zoom view to the default position and zoom level + */ +const handleReset = () => { + if (panzoomInstance) { + panzoomInstance.moveTo(0, 0); + panzoomInstance.zoomAbs(0, 0, 1); + } +}; + +/** * Exports the current diagram as a PNG image + * Prompts user to select scale factor before export * @returns {Promise<void>} */ const handleExport = async () => { @@ -146,8 +163,13 @@ const handleExport = async () => { background: white; cursor: pointer; margin-top: 10px; + margin-right: 8px; `; + const cancelButton = document.createElement('button'); + cancelButton.textContent = 'Cancel'; + cancelButton.style.cssText = button.style.cssText; + const overlay = document.createElement('div'); overlay.style.cssText = ` position: fixed; @@ -164,13 +186,25 @@ const handleExport = async () => { resolve(Number(scaleSelect.value)); }; + cancelButton.onclick = () => { + document.body.removeChild(overlay); + resolve(null); + }; + dialog.appendChild(title); dialog.appendChild(scaleSelect); - dialog.appendChild(button); + const buttonContainer = document.createElement('div'); + buttonContainer.style.cssText = 'display: flex; justify-content: center; gap: 8px;'; + buttonContainer.appendChild(button); + buttonContainer.appendChild(cancelButton); + dialog.appendChild(buttonContainer); overlay.appendChild(dialog); document.body.appendChild(overlay); }); + // If user cancelled, return early + if (scale === null) return; + const canvas = await html2canvas(preview, { backgroundColor: null, scale, @@ -190,6 +224,7 @@ const handleExport = async () => { /** * Exports the current diagram as an SVG file + * Resets view before export to ensure complete diagram is captured * @returns {Promise<void>} */ const handleExportSvg = async () => { @@ -228,16 +263,6 @@ const handleExportSvg = async () => { } }; -/** - * Resets the pan/zoom view to the default position - */ -const handleReset = () => { - if (panzoomInstance) { - panzoomInstance.moveTo(0, 0); - panzoomInstance.zoomAbs(0, 0, 1); - } -}; - // Event Handlers const debouncedRender = debounce(renderMermaid, 300); input.addEventListener('input', (e) => { |