about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--html/merfolk/app.js51
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) => {