From 7413f2a4798ac61bc157d97b4e06dfc4f8fecb17 Mon Sep 17 00:00:00 2001 From: Daniel Vazome <46573198+vazome@users.noreply.github.com> Date: Thu, 19 Jun 2025 07:09:00 +0000 Subject: [PATCH 1/5] fix(mermaid): zoom and reset digram relative to the browser window zoom --- quartz/components/scripts/mermaid.inline.ts | 37 +++++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/quartz/components/scripts/mermaid.inline.ts b/quartz/components/scripts/mermaid.inline.ts index 19ef24db1..6c38902d3 100644 --- a/quartz/components/scripts/mermaid.inline.ts +++ b/quartz/components/scripts/mermaid.inline.ts @@ -102,16 +102,22 @@ class DiagramPanZoom { private zoom(delta: number) { const newScale = Math.min(Math.max(this.scale + delta, this.MIN_SCALE), this.MAX_SCALE) - // Zoom around center - const rect = this.content.getBoundingClientRect() - const centerX = rect.width / 2 - const centerY = rect.height / 2 + // Zoom around the center of the container viewport, not the content + const containerRect = this.container.getBoundingClientRect() + const centerX = containerRect.width / 2 + const centerY = containerRect.height / 2 - const scaleDiff = newScale - this.scale - this.currentPan.x -= centerX * scaleDiff - this.currentPan.y -= centerY * scaleDiff + // Calculate the point we're zooming around relative to current transform + const zoomPointX = (centerX - this.currentPan.x) / this.scale + const zoomPointY = (centerY - this.currentPan.y) / this.scale + // Update scale 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() } @@ -121,11 +127,18 @@ class DiagramPanZoom { private resetTransform() { this.scale = 1 + + // Get container and SVG dimensions + const containerRect = this.container.getBoundingClientRect() const svg = this.content.querySelector("svg")! + const svgRect = svg.getBoundingClientRect() + + // Calculate center position relative to container this.currentPan = { - x: svg.getBoundingClientRect().width / 2, - y: svg.getBoundingClientRect().height / 2, + x: (containerRect.width - svgRect.width) / 2, + y: (containerRect.height - svgRect.height) / 2, } + this.updateTransform() } } @@ -237,8 +250,10 @@ document.addEventListener("nav", async () => { popupContainer.classList.add("active") container.style.cursor = "grab" - // Initialize pan-zoom after showing the popup - panZoom = new DiagramPanZoom(container, content) + // Initialize pan-zoom after showing the popup and let the layout settle + requestAnimationFrame(() => { + panZoom = new DiagramPanZoom(container, content) + }) } function hideMermaid() { From dc5602504e7f131e66426f6f443c434c6372f3f4 Mon Sep 17 00:00:00 2001 From: vazome Date: Thu, 19 Jun 2025 11:21:24 +0400 Subject: [PATCH 2/5] prettier --- quartz/components/scripts/mermaid.inline.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quartz/components/scripts/mermaid.inline.ts b/quartz/components/scripts/mermaid.inline.ts index 6c38902d3..9436fe87c 100644 --- a/quartz/components/scripts/mermaid.inline.ts +++ b/quartz/components/scripts/mermaid.inline.ts @@ -127,18 +127,18 @@ class DiagramPanZoom { private resetTransform() { this.scale = 1 - + // Get container and SVG dimensions const containerRect = this.container.getBoundingClientRect() const svg = this.content.querySelector("svg")! const svgRect = svg.getBoundingClientRect() - + // Calculate center position relative to container this.currentPan = { x: (containerRect.width - svgRect.width) / 2, y: (containerRect.height - svgRect.height) / 2, } - + this.updateTransform() } } From 4594f8225e74afdcd6efdadc48797aef61d522f2 Mon Sep 17 00:00:00 2001 From: vazome Date: Sat, 21 Jun 2025 04:51:28 +0400 Subject: [PATCH 3/5] mermaid-controls adjust --- quartz/components/styles/mermaid.inline.scss | 29 ++++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/quartz/components/styles/mermaid.inline.scss b/quartz/components/styles/mermaid.inline.scss index f25448da5..101a49fce 100644 --- a/quartz/components/styles/mermaid.inline.scss +++ b/quartz/components/styles/mermaid.inline.scss @@ -53,7 +53,7 @@ pre { } & > #mermaid-space { - border: 1px solid var(--lightgray); + border: 0.2vh solid var(--lightgray); background-color: var(--light); border-radius: 5px; position: fixed; @@ -86,14 +86,14 @@ pre { & > .mermaid-controls { position: absolute; - bottom: 20px; - right: 20px; + bottom: 2.5vh; + right: 2.5vw; display: flex; - gap: 8px; - padding: 8px; + gap: 0.5vw; + padding: 1vh 0.5vw; background: var(--light); - border: 1px solid var(--lightgray); - border-radius: 6px; + border: 0.2vh solid var(--lightgray); + border-radius: 0.8vh; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); z-index: 2; @@ -101,15 +101,15 @@ pre { display: flex; align-items: center; justify-content: center; - width: 32px; - height: 32px; + width: 4.5vh; + height: 4.5vh; padding: 0; - border: 1px solid var(--lightgray); + border: 0.2vh solid var(--lightgray); background: var(--light); color: var(--dark); - border-radius: 4px; + border-radius: 0.5vh; cursor: pointer; - font-size: 16px; + font-size: 2vh; font-family: var(--bodyFont); transition: all 0.2s ease; @@ -121,11 +121,10 @@ pre { transform: translateY(1px); } - // Style the reset button differently &:nth-child(2) { width: auto; - padding: 0 12px; - font-size: 14px; + padding: 0 1vw; + font-size: 2vh; } } } From b2f9f5a2ac1804059f0d0ed7133a153ee1ae8831 Mon Sep 17 00:00:00 2001 From: vazome Date: Sat, 21 Jun 2025 04:53:48 +0400 Subject: [PATCH 4/5] mermaid-controls adjust --- quartz/components/styles/mermaid.inline.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quartz/components/styles/mermaid.inline.scss b/quartz/components/styles/mermaid.inline.scss index 101a49fce..84f987f56 100644 --- a/quartz/components/styles/mermaid.inline.scss +++ b/quartz/components/styles/mermaid.inline.scss @@ -124,7 +124,7 @@ pre { &:nth-child(2) { width: auto; padding: 0 1vw; - font-size: 2vh; + font-size: 2vh; } } } From 36e16cd195414492deba76c4d8d4f836de88b767 Mon Sep 17 00:00:00 2001 From: vazome Date: Sat, 21 Jun 2025 06:42:25 +0400 Subject: [PATCH 5/5] mermaid-controls adjust --- quartz/components/scripts/mermaid.inline.ts | 27 ++++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/quartz/components/scripts/mermaid.inline.ts b/quartz/components/scripts/mermaid.inline.ts index 9436fe87c..23607afe8 100644 --- a/quartz/components/scripts/mermaid.inline.ts +++ b/quartz/components/scripts/mermaid.inline.ts @@ -12,6 +12,7 @@ class DiagramPanZoom { private scale = 1 private readonly MIN_SCALE = 0.5 private readonly MAX_SCALE = 3 + private resizeTimeout?: number cleanups: (() => void)[] = [] @@ -29,7 +30,7 @@ class DiagramPanZoom { const mouseDownHandler = this.onMouseDown.bind(this) const mouseMoveHandler = this.onMouseMove.bind(this) const mouseUpHandler = this.onMouseUp.bind(this) - const resizeHandler = this.resetTransform.bind(this) + const resizeHandler = this.onResize.bind(this) this.container.addEventListener("mousedown", mouseDownHandler) document.addEventListener("mousemove", mouseMoveHandler) @@ -44,10 +45,20 @@ class DiagramPanZoom { ) } + private onResize() { + if (this.resizeTimeout) { + clearTimeout(this.resizeTimeout) + } + this.resizeTimeout = window.setTimeout(() => this.resetTransform(), 50) + } + cleanup() { for (const cleanup of this.cleanups) { cleanup() } + if (this.resizeTimeout) { + clearTimeout(this.resizeTimeout) + } } private setupNavigationControls() { @@ -126,17 +137,21 @@ class DiagramPanZoom { } private resetTransform() { - this.scale = 1 - - // Get container and SVG dimensions + // Get container dimensions const containerRect = this.container.getBoundingClientRect() const svg = this.content.querySelector("svg")! + const svgRect = svg.getBoundingClientRect() + // svgRect is scaled by this.scale. We want the unscaled size. + const svgWidth = svgRect.width / this.scale + const svgHeight = svgRect.height / this.scale + + this.scale = 1 // Calculate center position relative to container this.currentPan = { - x: (containerRect.width - svgRect.width) / 2, - y: (containerRect.height - svgRect.height) / 2, + x: (containerRect.width - svgWidth) / 2, + y: (containerRect.height - svgHeight) / 2, } this.updateTransform()