fix(mermaid): zoom and reset digram relative to the browser window zoom

This commit is contained in:
Daniel Vazome 2025-06-19 07:09:00 +00:00 committed by vazome
parent 52a5196f38
commit 7413f2a479
No known key found for this signature in database

View File

@ -102,16 +102,22 @@ class DiagramPanZoom {
private zoom(delta: number) { private zoom(delta: number) {
const newScale = Math.min(Math.max(this.scale + delta, this.MIN_SCALE), this.MAX_SCALE) const newScale = Math.min(Math.max(this.scale + delta, this.MIN_SCALE), this.MAX_SCALE)
// Zoom around center // Zoom around the center of the container viewport, not the content
const rect = this.content.getBoundingClientRect() const containerRect = this.container.getBoundingClientRect()
const centerX = rect.width / 2 const centerX = containerRect.width / 2
const centerY = rect.height / 2 const centerY = containerRect.height / 2
const scaleDiff = newScale - this.scale // Calculate the point we're zooming around relative to current transform
this.currentPan.x -= centerX * scaleDiff const zoomPointX = (centerX - this.currentPan.x) / this.scale
this.currentPan.y -= centerY * scaleDiff const zoomPointY = (centerY - this.currentPan.y) / this.scale
// Update scale
this.scale = newScale this.scale = newScale
// Adjust pan to keep the zoom point in the same screen position
this.currentPan.x = centerX - zoomPointX * this.scale
this.currentPan.y = centerY - zoomPointY * this.scale
this.updateTransform() this.updateTransform()
} }
@ -121,11 +127,18 @@ class DiagramPanZoom {
private resetTransform() { private resetTransform() {
this.scale = 1 this.scale = 1
// Get container and SVG dimensions
const containerRect = this.container.getBoundingClientRect()
const svg = this.content.querySelector("svg")! const svg = this.content.querySelector("svg")!
const svgRect = svg.getBoundingClientRect()
// Calculate center position relative to container
this.currentPan = { this.currentPan = {
x: svg.getBoundingClientRect().width / 2, x: (containerRect.width - svgRect.width) / 2,
y: svg.getBoundingClientRect().height / 2, y: (containerRect.height - svgRect.height) / 2,
} }
this.updateTransform() this.updateTransform()
} }
} }
@ -237,8 +250,10 @@ document.addEventListener("nav", async () => {
popupContainer.classList.add("active") popupContainer.classList.add("active")
container.style.cursor = "grab" container.style.cursor = "grab"
// Initialize pan-zoom after showing the popup // Initialize pan-zoom after showing the popup and let the layout settle
requestAnimationFrame(() => {
panZoom = new DiagramPanZoom(container, content) panZoom = new DiagramPanZoom(container, content)
})
} }
function hideMermaid() { function hideMermaid() {