UNPKG

@matechat/core

Version:

前端智能化场景解决方案UI库,轻松构建你的AI应用。

128 lines (127 loc) 5.33 kB
class h { constructor(t = {}) { this.config = t, this.mermaidInstance = null, this.isLoading = !1, this.lastValidResult = "", this.viewStateMap = /* @__PURE__ */ new WeakMap(), this.containerHeight = 400; } async loadMermaid() { if (this.mermaidInstance) return this.mermaidInstance; if (this.isLoading) return new Promise((t) => { const e = () => { this.mermaidInstance ? t(this.mermaidInstance) : setTimeout(e, 50); }; e(); }); this.isLoading = !0; try { const { default: t } = await import("mermaid"); return t.initialize({ theme: this.config.theme || "default", startOnLoad: !1, suppressErrorRendering: !0, ...this.config }), this.mermaidInstance = t, t; } catch (t) { throw console.error("Failed to load mermaid:", t), new Error("Failed to load mermaid library"); } finally { this.isLoading = !1; } } async renderToContainer(t, e, s = "light") { const a = await this.renderMermaid(e, s); t.innerHTML = a; const i = t.querySelector("svg"); i && (this.initViewState(t, i), this.applyTransform(t, i), i.addEventListener("mousedown", (o) => this.onSvgMouseDown(o, t, i))); } initViewState(t, e) { let s = e.getAttribute("viewBox"), a = 0, i = 0; if (s) { const l = s.split(/\s+/); a = parseFloat(l[2]), i = parseFloat(l[3]); } else a = e.width.baseVal.value || e.getBoundingClientRect().width, i = e.height.baseVal.value || e.getBoundingClientRect().height; const o = t.clientWidth || 0, r = this.containerHeight; let n = 1; a && i && o && r && (n = Math.min(o / a, r / i, 1)), this.viewStateMap.set(t, { scale: n, offsetX: 0, offsetY: 0, dragging: !1, dragStart: { x: 0, y: 0 }, lastOffset: { x: 0, y: 0 } }); } applyTransform(t, e) { const s = this.viewStateMap.get(t); s && (e.style.position = "absolute", e.style.left = "50%", e.style.top = "50%", e.style.transform = `translate(-50%, -50%) translate(${s.offsetX}px, ${s.offsetY}px) scale(${s.scale})`, e.style.transformOrigin = "center center", e.style.cursor = s.dragging ? "grabbing" : "grab"); } zoomIn(t) { const e = t.querySelector("svg"), s = this.viewStateMap.get(t); e && s && (s.scale = Math.min(s.scale + 0.2, 3), this.applyTransform(t, e)); } zoomOut(t) { const e = t.querySelector("svg"), s = this.viewStateMap.get(t); e && s && (s.scale = Math.max(s.scale - 0.2, 0.2), this.applyTransform(t, e)); } reset(t) { const e = t.querySelector("svg"); e && (this.initViewState(t, e), this.applyTransform(t, e)); } async download(t, e = "diagram.png") { const s = t.querySelector("svg"); if (s) try { const a = s.cloneNode(!0), i = new XMLSerializer().serializeToString(a), o = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(i)}`, r = new Image(); await new Promise((d, m) => { r.onload = () => d(), r.onerror = (c) => m(new Error("Image loading failed")), r.src = o; }); const n = document.createElement("canvas"), l = n.getContext("2d"); if (!l) throw new Error("Canvas context not available"); n.width = r.width * 2, n.height = r.height * 2, l.fillStyle = "white", l.fillRect(0, 0, n.width, n.height), l.drawImage(r, 0, 0), n.toBlob((d) => { if (!d) { console.error("Failed to create blob from canvas"); return; } const m = URL.createObjectURL(d), c = document.createElement("a"); c.href = m, c.download = e, document.body.appendChild(c), c.click(), setTimeout(() => { document.body.removeChild(c), URL.revokeObjectURL(m); }, 100); }, "image/png"); } catch (a) { console.error("Failed to download diagram:", a); } } onSvgMouseDown(t, e, s) { const a = this.viewStateMap.get(e); if (!a) return; a.dragging = !0, a.dragStart = { x: t.clientX, y: t.clientY }, a.lastOffset = { x: a.offsetX, y: a.offsetY }; const i = (r) => this.onSvgMouseMove(r, e, s), o = () => this.onSvgMouseUp(e, s, i, o); document.addEventListener("mousemove", i), document.addEventListener("mouseup", o), this.applyTransform(e, s); } onSvgMouseMove(t, e, s) { const a = this.viewStateMap.get(e); !a || !a.dragging || (a.offsetX = a.lastOffset.x + (t.clientX - a.dragStart.x), a.offsetY = a.lastOffset.y + (t.clientY - a.dragStart.y), this.applyTransform(e, s)); } onSvgMouseUp(t, e, s, a) { const i = this.viewStateMap.get(t); i && (i.dragging = !1, document.removeEventListener("mousemove", s), document.removeEventListener("mouseup", a), this.applyTransform(t, e)); } async renderMermaid(t, e = "light") { try { const s = await this.loadMermaid(); this.config.theme !== e && (this.config.theme = e, s.initialize({ startOnLoad: !1, suppressErrorRendering: !0, theme: e === "dark" ? "dark" : "default", ...this.config })); const a = `mc_mermaid_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, { svg: i } = await s.render(a, t); return this.lastValidResult = i, i; } catch { return this.lastValidResult; } } } export { h as MermaidService };