<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mermaid Diagram with Zoom and Pan</title> <!-- Include the Mermaid library via CDN --> <script src="https://cdn.jsdelivr.net/npm/mermaid@10.9.0/dist/mermaid.min.js"></script> <!-- Include the Panzoom.js library --> <script src="https://cdn.jsdelivr.net/npm/panzoom@9.4.3/dist/panzoom.min.js"></script> <style> /* Container to hold the Mermaid diagram */ #mermaidContainer { width: 100%; max-width: 1200px; /* Control the max width */ height: 80vh; /* Control the height based on the viewport */ margin: auto; border: 1px solid #ddd; /* Optional: border for visibility */ position: relative; overflow: hidden; /* Ensure overflow is hidden */ } /* Position the zoom buttons at the top of the diagram */ #zoomControls { display: flex; justify-content: center; margin-bottom: 10px; } .zoom-btn { padding: 10px; margin: 0 5px; font-size: 16px; cursor: pointer; background-color: #007BFF; color: white; border: none; border-radius: 5px; } .zoom-btn:hover { background-color: #0056b3; } svg { width: 100%; /* Ensure the SVG fits the container width */ height: 100%; /* Ensure the SVG fits the container height */ } /* Styles for the log container */ #logContainer { margin-top: 20px; padding: 10px; border: 1px solid #ccc; background-color: #f9f9f9; max-height: 200px; overflow-y: auto; } </style> </head> <body> <h1>Mermaid Flowchart with Zoom and Pan</h1> <!-- Zoom Controls --> <div id="zoomControls"> <button class="zoom-btn" id="zoomIn">Zoom In</button> <button class="zoom-btn" id="zoomOut">Zoom Out</button> <button class="zoom-btn" id="resetZoom">Reset</button> </div> <!-- Mermaid diagram container --> <div id="mermaidContainer" class="mermaid"> flowchart TD A[Cloud User] -->|CHF/EUR/...| B(CLOUD MARKET PLACE<br>Discount based on position<br>in TF Liquidity Pool.) A[Cloud User] -->|CHF/EUR/...| B2((ThreeFold<br>Liquidity Pool)) B2 -->|TFT or INCA| B B -->|TFT or INCA| C{Proof Of Utilization} G[FARMING GRANTS<br>40m Tokens / Month] --> I{Proof Of Capacity<br>uptime, location, ...} --> D C -->|80%| D[ThreeFold Farmers] C -->|10%| E[ThreeFold Cooperative] C -->|10%| F[Validators<br>Commercial Partners] </div> <!-- Log container --> <div id="logContainer"></div> <script> function log(message) { const logContainer = document.getElementById('logContainer'); logContainer.innerHTML += message + '<br>'; console.log(message); } document.addEventListener('DOMContentLoaded', function () { // Initialize Mermaid mermaid.initialize({ startOnLoad: true }); // Watch for changes in the DOM to detect when the SVG is rendered const observer = new MutationObserver(function () { const svgElement = document.querySelector('#mermaidContainer svg'); if (svgElement) { // Once the SVG is found, disconnect the observer observer.disconnect(); // Log SVG details log('SVG found:'); log(`- Width: ${svgElement.width.baseVal.value}`); log(`- Height: ${svgElement.height.baseVal.value}`); log(`- ViewBox: ${svgElement.getAttribute('viewBox')}`); // Set the viewBox on the SVG element to fit the entire diagram const svgBox = svgElement.getBBox(); svgElement.setAttribute('viewBox', `0 0 ${svgBox.width} ${svgBox.height}`); log(`- Updated ViewBox: ${svgElement.getAttribute('viewBox')}`); // Log the number of child elements log(`- Number of child elements: ${svgElement.children.length}`); // Apply Panzoom to enable zoom and pan functionality const panzoomInstance = panzoom(svgElement, { maxScale: 10, // Maximum zoom level minScale: 0.5, // Minimum zoom level contain: 'outside', // Ensure the SVG stays within bounds panOnlyWhenZoomed: true, // Enable panning only when zoomed initialX: 300, initialY: 500, initialZoom: 2 }); log('Panzoom initialized'); // Enable zooming with the mouse wheel, marking the event listener as passive svgElement.parentElement.addEventListener('wheel', panzoomInstance.zoomWithWheel, { passive: true }); // Hook up the zoom buttons document.getElementById('zoomIn').addEventListener('click', function() { const currentScale = panzoomInstance.getScale(); panzoomInstance.scaleTo(svgElement.clientWidth / 2, svgElement.clientHeight / 2, currentScale * 1.2); log(`Zoomed in. New scale: ${panzoomInstance.getScale()}`); }); document.getElementById('zoomOut').addEventListener('click', function() { const currentScale = panzoomInstance.getScale(); panzoomInstance.scaleTo(svgElement.clientWidth / 2, svgElement.clientHeight / 2, currentScale * 0.8); log(`Zoomed out. New scale: ${panzoomInstance.getScale()}`); }); document.getElementById('resetZoom').addEventListener('click', function() { panzoomInstance.reset(); // Reset zoom and pan to the initial state log('Zoom reset'); }); } }); // Observe changes inside the mermaidContainer const container = document.querySelector('#mermaidContainer'); observer.observe(container, { childList: true, subtree: true }); }); </script> </body> </html>