document.addEventListener("DOMContentLoaded", function () {
mermaid.initialize({ startOnLoad: true });
setTimeout(addZoomPan, 300);
});
document$.subscribe(function () {
mermaid.init(undefined, document.querySelectorAll(".mermaid"));
setTimeout(addZoomPan, 300);
});
function addZoomPan() {
const svgs = document.querySelectorAll('pre.mermaid svg, .mermaid svg');
svgs.forEach((svg) => {
if (svg.dataset.zoomEnabled === 'true') {
return;
}
svg.dataset.zoomEnabled = 'true';
let scale = 1;
let panning = false;
let pointX = 0;
let pointY = 0;
let start = { x: 0, y: 0 };
const g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
while (svg.firstChild) {
g.appendChild(svg.firstChild);
}
svg.appendChild(g);
svg.addEventListener('wheel', (e) => {
e.preventDefault();
const delta = e.deltaY > 0 ? 0.9 : 1.1;
scale *= delta;
scale = Math.min(Math.max(0.5, scale), 5);
const rect = svg.getBoundingClientRect();
const offsetX = e.clientX - rect.left;
const offsetY = e.clientY - rect.top;
pointX = offsetX - (offsetX - pointX) * delta;
pointY = offsetY - (offsetY - pointY) * delta;
g.style.transform = `translate(${pointX}px, ${pointY}px) scale(${scale})`;
g.style.transformOrigin = '0 0';
});
svg.addEventListener('mousedown', (e) => {
panning = true;
start = { x: e.clientX - pointX, y: e.clientY - pointY };
svg.style.cursor = 'grabbing';
});
svg.addEventListener('mousemove', (e) => {
if (!panning) return;
e.preventDefault();
pointX = e.clientX - start.x;
pointY = e.clientY - start.y;
g.style.transform = `translate(${pointX}px, ${pointY}px) scale(${scale})`;
});
svg.addEventListener('mouseup', () => {
panning = false;
svg.style.cursor = 'grab';
});
svg.addEventListener('mouseleave', () => {
panning = false;
svg.style.cursor = 'default';
});
svg.addEventListener('dblclick', () => {
scale = 1;
pointX = 0;
pointY = 0;
g.style.transform = 'translate(0, 0) scale(1)';
});
svg.style.cursor = 'grab';
});
}