This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Friday, 07 November 2025
Εγώ... ένας τύπος από το .net βρήκε επιτέλους το κουράγιο να βουτήξει τα δάχτυλα των ποδιών μου στον κόσμο των πακέτων! Γοργόνα.js είναι αρκετά σκοτεινό και αρκετά περίεργο ότι θα μπορούσα πραγματικά να παραδώσει κάτι χρήσιμο!
Μετά την κατασκευή κάποιων πραγματικά χρήσιμες βελτιώσεις για διαγράμματα Mermaid.js (διαδραστικό pan/zoom, fullscreen lightbox, εξαγωγή σε PNG/SVG, και αυτόματη αλλαγή θέματος), αποφάσισα ότι ήταν καιρός να τα συσκευάσει σωστά και να τα μοιραστούν με την κοινότητα. @mostlylucid/mermaid-enhancements ως πακέτο παραγωγής-έτοιμο npm.
ΣΗΜΕΙΩΣΗ: Εξακολουθεί να εργάζεται για την απελευθέρωση. Μείνετε συντονισμένοι (το πρώτο πακέτο μου npm έτσι παίρνει λίγο)
Χρησιμοποιώ αυτές τις βελτιώσεις σε όλο το blog μου εδώ και λίγο καιρό, και έχουν γίνει απαραίτητες για να εργαστούν με σύνθετα διαγράμματα Γοργόνας. Τα χαρακτηριστικά περιλαμβάνουν:
Δεδομένου ότι αντιγράφω τον ίδιο κώδικα μεταξύ των έργων, ήταν λογικό να δημιουργήσουμε ένα κατάλληλο πακέτο NPM που ο καθένας θα μπορούσε να χρησιμοποιήσει.
Έχω δημιουργήσει μια επαγγελματική δομή πακέτου με την υποστήριξη TypeScript:
mostlylucid-mermaid/
├── src/
│ ├── index.ts # Main entry point
│ ├── enhancements.ts # Pan/zoom/export functionality
│ ├── theme-switcher.ts # Theme switching logic
│ ├── types.ts # TypeScript type definitions
│ └── styles.css # Complete styling
├── examples/
│ └── demo.html # Full-featured demo
├── dist/ # Built output (generated)
├── package.json
├── tsconfig.json
├── README.md
├── QUICKSTART.md
├── PUBLISHING.md
└── LICENSE
Το πακέτο χρησιμοποιεί το TypeScript για την ασφάλεια του τύπου και την καλύτερη εμπειρία του προγραμματιστή, αλλά καταρτίζει μέχρι JavaScript για μέγιστη συμβατότητα.
Εδώ είναι πώς τα συστατικά ταιριάζουν μεταξύ τους:
Έτσι βλέπετε ότι είναι αρκετά συμπαγής και έχει κάποια χρήσιμη λειτουργικότητα πέρα από απλά στατικά διαγράμματα. Πάντα με ενοχλούσε το πώς MASSIVE ήταν στη σελίδα, έτσι ώστε αυτό φαινόταν μια λογική προσέγγιση στο μέγεθος refuckng διατηρώντας τη χρησιμότητα.
graph TD
A[User Initializes] --> B[init Function]
B --> C[initMermaid]
B --> D[enhanceMermaidDiagrams]
C --> E[Theme Detection]
C --> F[Event Listeners]
C --> G[Mermaid Rendering]
E --> E1[Global State]
E --> E2[LocalStorage]
E --> E3[DOM Class]
E --> E4[OS Preference]
F --> F1[Custom Events]
F --> F2[Media Query]
G --> H[Apply Enhancements]
D --> H
H --> I[Wrap Diagrams]
H --> J[Init Pan/Zoom]
H --> K[Add Controls]
I --> L[Interactive Diagram]
J --> L
K --> L
L --> M[User Interactions]
M --> M1[Zoom In/Out]
M --> M2[Pan]
M --> M3[Fullscreen]
M --> M4[Export PNG/SVG]
style A stroke:#059669,stroke-width:3px,color:#10b981
style L stroke:#2563eb,stroke-width:3px,color:#3b82f6
style M stroke:#7c3aed,stroke-width:3px,color:#8b5cf6
Πρώτον, ορίζω τους ολοκληρωμένους τύπους TypeScript:
// src/types.ts
export interface PanZoomInstance {
zoom(scale: number): void;
zoomIn(): void;
zoomOut(): void;
reset(): void;
fit(): void;
center(): void;
resize(): void;
destroy(): void;
isPanEnabled(): boolean;
enablePan(enabled: boolean): void;
}
export type ExportFormat = 'png' | 'svg';
export type Theme = 'dark' | 'default';
export type ControlAction = 'fullscreen' | 'zoomIn' | 'zoomOut' |
'reset' | 'pan' | 'exportPng' | 'exportSvg';
export interface EnhancementConfig {
icons?: IconConfig;
controls?: {
fullscreen?: boolean;
zoom?: boolean;
pan?: boolean;
export?: boolean;
};
}
Το κύριο σημείο εισόδου είναι απλό:
// src/index.ts
export {
enhanceMermaidDiagrams,
cleanupMermaidEnhancements
} from './enhancements.js';
export {
initMermaid
} from './theme-switcher.js';
export async function init() {
await initMermaid();
}
export default {
init,
initMermaid,
enhanceMermaidDiagrams,
};
Η λογική ενίσχυσης τυλίγει κάθε διάγραμμα με χειριστήρια και αρχικοποιεί svg-pan-zoom:
// src/enhancements.ts
import svgPanZoom from 'svg-pan-zoom';
import { toPng, toSvg } from 'html-to-image';
const panZoomInstances = new Map();
function initPanZoom(svgElement: SVGElement, diagramId: string) {
// Clean up existing instance if present
if (panZoomInstances.has(diagramId)) {
try {
panZoomInstances.get(diagramId).destroy();
} catch (e) {
console.warn('Failed to destroy existing pan-zoom instance:', e);
}
panZoomInstances.delete(diagramId);
}
try {
const panZoomInstance = svgPanZoom(svgElement, {
zoomEnabled: true,
controlIconsEnabled: false,
fit: true,
center: true,
minZoom: 0.1,
maxZoom: 10,
zoomScaleSensitivity: 0.3,
dblClickZoomEnabled: true,
mouseWheelZoomEnabled: true,
preventMouseEventsDefault: true,
contain: false
});
panZoomInstances.set(diagramId, panZoomInstance);
return panZoomInstance;
} catch (error) {
console.error('Failed to initialize pan-zoom:', error);
return null;
}
}
Τα κουμπιά ελέγχου δημιουργούνται δυναμικά:
function createControlButtons(container: HTMLElement, diagramId: string) {
if (container.querySelector('.mermaid-controls')) {
return;
}
const controlsDiv = document.createElement('div');
controlsDiv.className = 'mermaid-controls';
const buttons = [
{ icon: 'bx-fullscreen', title: 'Fullscreen', action: 'fullscreen' },
{ icon: 'bx-zoom-in', title: 'Zoom In', action: 'zoomIn' },
{ icon: 'bx-zoom-out', title: 'Zoom Out', action: 'zoomOut' },
{ icon: 'bx-reset', title: 'Reset View', action: 'reset' },
{ icon: 'bx-move', title: 'Pan', action: 'pan' },
{ icon: 'bx-image', title: 'Export as PNG', action: 'exportPng' },
{ icon: 'bx-code-alt', title: 'Export as SVG', action: 'exportSvg' }
];
buttons.forEach(btn => {
const button = document.createElement('button');
button.className = `mermaid-control-btn bx ${btn.icon}`;
button.setAttribute('title', btn.title);
button.setAttribute('aria-label', btn.title);
button.setAttribute('data-action', btn.action);
button.setAttribute('data-diagram-id', diagramId);
controlsDiv.appendChild(button);
});
container.appendChild(controlsDiv);
}
Η εφαρμογή των εξ
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.