Skip to content

feat: add SVG/PNG download overlay for diagram preview#1568

Merged
yanglbme merged 2 commits into
mainfrom
feat/diagram-svg-png-download
May 24, 2026
Merged

feat: add SVG/PNG download overlay for diagram preview#1568
yanglbme merged 2 commits into
mainfrom
feat/diagram-svg-png-download

Conversation

@yanglbme
Copy link
Copy Markdown
Member

@yanglbme yanglbme commented May 24, 2026

Summary

Add hover download bars to Mermaid and PlantUML diagram containers in the preview panel, allowing users to download diagrams as .svg or .png.

Changes

New file: apps/web/src/utils/diagramDownload.ts

  • downloadDiagramSvg() — serializes the SVG to a Blob and triggers a download
  • downloadDiagramPng() — renders SVG to a <canvas> via a percent-encoded data: URL (avoids the tainted-canvas SecurityError from using a blob: URL in Chromium), then downloads the PNG
  • setupDiagramDownloadOverlay() — installs a MutationObserver on #output to detect when Mermaid/PlantUML inject SVGs asynchronously and injects a styled download bar into each diagram container
  • pause() / resume() API — removes bars from the DOM and suspends the observer during copy/export operations so bars never appear in the exported content

Modified: apps/web/src/components/editor/PreviewPanel.vue

  • Mount/unmount the overlay with onMounted / onUnmounted
  • Watch isCoping prop to call pause() before and resume() after the WeChat copy pipeline

Modified: apps/web/src/utils/index.ts

  • getHtmlContent() now clones #output and strips .diagram-download-bar nodes before returning innerHTML, so HTML/PDF exports are unaffected

Modified: apps/web/src/stores/export.ts

  • downloadAsCardImage() injects a temporary CSS rule to display: none all .diagram-download-bar elements during html-to-image capture

- Inject a hover download bar into Mermaid and PlantUML diagram containers
- SVG download uses Blob + createObjectURL; PNG uses canvas with a data-URL
  source to avoid the tainted-canvas SecurityError in Chromium
- MutationObserver detects async SVG injection and adds bars automatically
- pause()/resume() API hides bars during copy/export to keep output clean
- getHtmlContent() clones #output and strips .diagram-download-bar nodes
- downloadAsCardImage hides bars via temporary CSS during html-to-image
Copilot AI review requested due to automatic review settings May 24, 2026 03:12
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 24, 2026

🚀 Cloudflare Workers Preview has been successfully deployed!

Preview URL: https://md-pr-1568.doocs.workers.dev

Built with commit 144657a

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 24, 2026

🚀 Surge Preview has been successfully deployed!

Preview URL: https://doocs-md-preview-pr-1568.surge.sh

Built with commit 144657a

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an interactive download overlay to rendered Mermaid and PlantUML diagrams in the preview panel, enabling users to download diagrams as SVG or PNG while ensuring exports/copy flows exclude the overlay UI.

Changes:

  • Added diagramDownload.ts utilities to download SVG/PNG and to inject a hover-based download bar via a MutationObserver.
  • Wired overlay lifecycle into PreviewPanel.vue (mount/unmount + pause/resume during WeChat copy).
  • Ensured exports don’t include the overlay by stripping .diagram-download-bar from HTML exports and hiding it during card-image capture.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
apps/web/src/utils/index.ts Clones #output and removes .diagram-download-bar nodes before exporting HTML.
apps/web/src/utils/diagramDownload.ts Implements SVG/PNG download helpers and an observer-driven overlay injector with pause/resume controls.
apps/web/src/stores/export.ts Adds a temporary CSS rule to hide .diagram-download-bar during html-to-image capture.
apps/web/src/components/editor/PreviewPanel.vue Mounts/unmounts the overlay and pauses it during copy; adds unscoped overlay styling.

Comment on lines +172 to +181
pointer-events: none;
transform: translateY(-6px);
transition: opacity 0.18s ease, transform 0.18s ease;
}

.mermaid-diagram:hover .diagram-download-bar,
.plantuml-diagram:hover .diagram-download-bar {
opacity: 1;
pointer-events: auto;
transform: translateY(0);
Comment thread apps/web/src/utils/diagramDownload.ts Outdated
Comment on lines +179 to +183
for (const node of addedNodes) {
if (node.nodeType !== Node.ELEMENT_NODE)
continue
const el = node as HTMLElement
if (el.matches(DIAGRAM_SELECTORS))
- Add visibility:hidden to .diagram-download-bar so opacity:0 buttons
  are not focusable; toggle visibility with zero-delay transition when
  the bar becomes visible
- Reveal bar on :focus-within so keyboard users can reach the buttons
- Replace per-mutation candidate scanning with a single requestAnimationFrame-
  batched scan() call to avoid redundant subtree queries on rapid re-renders
- Cancel pending rAF in pause() and cleanup() to prevent stale callbacks
@yanglbme yanglbme merged commit 34de255 into main May 24, 2026
2 checks passed
@yanglbme yanglbme deleted the feat/diagram-svg-png-download branch May 24, 2026 03:23
@github-actions
Copy link
Copy Markdown

🗑️ Cloudflare Workers preview deployment has been cleaned up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants