@markdy/renderer-dom 0.8.26 → 0.8.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +95 -11
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -808,13 +808,14 @@ function ensureAnnotationStyles(doc) {
|
|
|
808
808
|
doc.head.appendChild(style);
|
|
809
809
|
}
|
|
810
810
|
function positionForAnnotation(position, bounds, index) {
|
|
811
|
-
const pad =
|
|
811
|
+
const pad = 28;
|
|
812
|
+
const topPad = 68;
|
|
812
813
|
const p = (position ?? "").toLowerCase();
|
|
813
|
-
if (p.includes("top") && p.includes("right")) return { x: bounds.width - pad - 200, y:
|
|
814
|
-
if (p.includes("top") && p.includes("left")) return { x: pad, y:
|
|
814
|
+
if (p.includes("top") && p.includes("right")) return { x: bounds.width - pad - 200, y: topPad + index * 48 };
|
|
815
|
+
if (p.includes("top") && p.includes("left")) return { x: pad, y: topPad + index * 48 };
|
|
815
816
|
if (p.includes("bottom") && p.includes("right")) return { x: bounds.width - pad - 200, y: bounds.height - pad - 40 };
|
|
816
817
|
if (p.includes("bottom") && p.includes("left")) return { x: pad, y: bounds.height - pad - 40 };
|
|
817
|
-
return { x: bounds.width - pad - 200, y:
|
|
818
|
+
return { x: bounds.width - pad - 200, y: topPad + index * 48 };
|
|
818
819
|
}
|
|
819
820
|
function mountAnnotations(layer, annotations, nodes, theme, bounds) {
|
|
820
821
|
if (annotations.length === 0) return;
|
|
@@ -2110,11 +2111,16 @@ function createDiagram(opts) {
|
|
|
2110
2111
|
const totalDurationMs = plan.duration * 1e3;
|
|
2111
2112
|
const durationSeconds = plan.duration;
|
|
2112
2113
|
const viewport = document.createElement("div");
|
|
2114
|
+
viewport.className = "markdy-viewport";
|
|
2113
2115
|
Object.assign(viewport.style, {
|
|
2114
2116
|
position: "relative",
|
|
2115
2117
|
width: "100%",
|
|
2118
|
+
height: "100%",
|
|
2119
|
+
maxWidth: "100%",
|
|
2120
|
+
maxHeight: "100%",
|
|
2116
2121
|
aspectRatio: `${plan.meta.width} / ${plan.meta.height}`,
|
|
2117
|
-
overflow: "hidden"
|
|
2122
|
+
overflow: "hidden",
|
|
2123
|
+
boxSizing: "border-box"
|
|
2118
2124
|
});
|
|
2119
2125
|
container.appendChild(viewport);
|
|
2120
2126
|
let progressEl = null;
|
|
@@ -2269,14 +2275,85 @@ function createDiagram(opts) {
|
|
|
2269
2275
|
nodeEls.set(node.id, el);
|
|
2270
2276
|
}
|
|
2271
2277
|
let fitScale = 1;
|
|
2278
|
+
let sceneOffsetX = 0;
|
|
2279
|
+
let sceneOffsetY = 0;
|
|
2280
|
+
function computeContentBounds() {
|
|
2281
|
+
if (!plan.nodes || plan.nodes.length === 0) {
|
|
2282
|
+
return { minX: 0, minY: 0, maxX: plan.meta.width, maxY: plan.meta.height, width: plan.meta.width, height: plan.meta.height };
|
|
2283
|
+
}
|
|
2284
|
+
let minX = Infinity;
|
|
2285
|
+
let minY = Infinity;
|
|
2286
|
+
let maxX = -Infinity;
|
|
2287
|
+
let maxY = -Infinity;
|
|
2288
|
+
for (const node of plan.nodes) {
|
|
2289
|
+
minX = Math.min(minX, node.x);
|
|
2290
|
+
minY = Math.min(minY, node.y);
|
|
2291
|
+
maxX = Math.max(maxX, node.x + node.width);
|
|
2292
|
+
maxY = Math.max(maxY, node.y + node.height);
|
|
2293
|
+
}
|
|
2294
|
+
for (const gb of plan.groupBoundaries ?? []) {
|
|
2295
|
+
minX = Math.min(minX, gb.x);
|
|
2296
|
+
minY = Math.min(minY, gb.y);
|
|
2297
|
+
maxX = Math.max(maxX, gb.x + gb.width);
|
|
2298
|
+
maxY = Math.max(maxY, gb.y + gb.height);
|
|
2299
|
+
}
|
|
2300
|
+
for (const bus of plan.treeBuses ?? []) {
|
|
2301
|
+
minX = Math.min(minX, bus.parentX, ...bus.childXs.length ? bus.childXs : [bus.parentX]);
|
|
2302
|
+
minY = Math.min(minY, bus.parentY, bus.branchY, bus.childY);
|
|
2303
|
+
maxX = Math.max(maxX, bus.parentX, ...bus.childXs.length ? bus.childXs : [bus.parentX]);
|
|
2304
|
+
maxY = Math.max(maxY, bus.parentY, bus.branchY, bus.childY);
|
|
2305
|
+
}
|
|
2306
|
+
if (plan.title) {
|
|
2307
|
+
minY = Math.min(minY, 20);
|
|
2308
|
+
}
|
|
2309
|
+
const pad = 36;
|
|
2310
|
+
minX = Math.max(0, minX - pad);
|
|
2311
|
+
minY = Math.max(0, minY - pad);
|
|
2312
|
+
maxX = Math.min(plan.meta.width, maxX + pad);
|
|
2313
|
+
maxY = Math.min(plan.meta.height, maxY + pad);
|
|
2314
|
+
const width = Math.max(maxX - minX, 200);
|
|
2315
|
+
const height = Math.max(maxY - minY, 140);
|
|
2316
|
+
return { minX, minY, maxX, maxY, width, height };
|
|
2317
|
+
}
|
|
2272
2318
|
function scaleScene() {
|
|
2273
|
-
const
|
|
2274
|
-
|
|
2319
|
+
const isBrowserLayout = (viewport.clientWidth || container.clientWidth || 0) > 0;
|
|
2320
|
+
if (!isBrowserLayout) {
|
|
2321
|
+
fitScale = 1;
|
|
2322
|
+
sceneOffsetX = 0;
|
|
2323
|
+
sceneOffsetY = 0;
|
|
2324
|
+
scene.style.left = "0px";
|
|
2325
|
+
scene.style.top = "0px";
|
|
2326
|
+
scene.style.transformOrigin = "0 0";
|
|
2327
|
+
scene.style.transform = "scale(1)";
|
|
2328
|
+
return;
|
|
2329
|
+
}
|
|
2330
|
+
const vWidth = viewport.clientWidth || container.clientWidth || plan.meta.width;
|
|
2331
|
+
const vHeight = viewport.clientHeight || container.clientHeight || vWidth * plan.meta.height / plan.meta.width;
|
|
2332
|
+
const canvasScaleX = vWidth / plan.meta.width;
|
|
2333
|
+
const canvasScaleY = vHeight / plan.meta.height;
|
|
2334
|
+
const baseCanvasScale = Math.min(canvasScaleX, canvasScaleY);
|
|
2335
|
+
const bounds = computeContentBounds();
|
|
2336
|
+
const contentScaleX = vWidth * 0.94 / bounds.width;
|
|
2337
|
+
const contentScaleY = vHeight * 0.94 / bounds.height;
|
|
2338
|
+
const optimalContentScale = Math.min(contentScaleX, contentScaleY);
|
|
2339
|
+
const chosenScale = Math.max(
|
|
2340
|
+
baseCanvasScale,
|
|
2341
|
+
Math.min(optimalContentScale, baseCanvasScale * 1.45)
|
|
2342
|
+
);
|
|
2343
|
+
fitScale = Number.isFinite(chosenScale) && chosenScale > 0 ? chosenScale : 1;
|
|
2344
|
+
const scaledWidth = plan.meta.width * fitScale;
|
|
2345
|
+
const scaledHeight = plan.meta.height * fitScale;
|
|
2346
|
+
sceneOffsetX = (vWidth - scaledWidth) / 2;
|
|
2347
|
+
sceneOffsetY = (vHeight - scaledHeight) / 2;
|
|
2348
|
+
scene.style.left = `${sceneOffsetX}px`;
|
|
2349
|
+
scene.style.top = `${sceneOffsetY}px`;
|
|
2350
|
+
scene.style.transformOrigin = "0 0";
|
|
2275
2351
|
scene.style.transform = `scale(${fitScale})`;
|
|
2276
2352
|
}
|
|
2277
2353
|
scaleScene();
|
|
2278
2354
|
const resizeObserver = typeof ResizeObserver === "function" ? new ResizeObserver(scaleScene) : null;
|
|
2279
2355
|
resizeObserver?.observe(viewport);
|
|
2356
|
+
if (container !== viewport) resizeObserver?.observe(container);
|
|
2280
2357
|
const edgeRuntimes = /* @__PURE__ */ new Map();
|
|
2281
2358
|
const edgeSceneId = createEdgeSceneId();
|
|
2282
2359
|
const sequenceAnims = plan.diagramType === "sequence" ? mountSequenceLayer(
|
|
@@ -2341,8 +2418,8 @@ function createDiagram(opts) {
|
|
|
2341
2418
|
function handleViewportWheel(event) {
|
|
2342
2419
|
event.preventDefault();
|
|
2343
2420
|
const rect = viewport.getBoundingClientRect();
|
|
2344
|
-
const pointerX = (event.clientX - rect.left) / fitScale;
|
|
2345
|
-
const pointerY = (event.clientY - rect.top) / fitScale;
|
|
2421
|
+
const pointerX = (event.clientX - rect.left - sceneOffsetX) / fitScale;
|
|
2422
|
+
const pointerY = (event.clientY - rect.top - sceneOffsetY) / fitScale;
|
|
2346
2423
|
const nextScale = Math.min(MAX_VIEWPORT_ZOOM, Math.max(MIN_VIEWPORT_ZOOM, viewportScale * Math.exp(-event.deltaY * VIEWPORT_ZOOM_STEP)));
|
|
2347
2424
|
if (nextScale === viewportScale) return;
|
|
2348
2425
|
const sceneX = (pointerX - viewportPanX) / viewportScale;
|
|
@@ -2809,6 +2886,8 @@ ${serializer2.serializeToString(clonedSvg)}`;
|
|
|
2809
2886
|
clonedScene.style.transform = `scale(${scale})`;
|
|
2810
2887
|
clonedScene.style.transformOrigin = "0 0";
|
|
2811
2888
|
clonedScene.style.position = "relative";
|
|
2889
|
+
clonedScene.style.left = "0px";
|
|
2890
|
+
clonedScene.style.top = "0px";
|
|
2812
2891
|
clonedScene.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2813
2892
|
if (options.transparentBackground) {
|
|
2814
2893
|
clonedScene.style.background = "transparent";
|
|
@@ -2853,7 +2932,10 @@ async function exportDiagramAsPng(containerEl, options = {}) {
|
|
|
2853
2932
|
const img = new Image();
|
|
2854
2933
|
await new Promise((resolve, reject) => {
|
|
2855
2934
|
img.onload = () => resolve();
|
|
2856
|
-
img.onerror = () =>
|
|
2935
|
+
img.onerror = () => {
|
|
2936
|
+
URL.revokeObjectURL(url);
|
|
2937
|
+
reject(new Error("Failed to rasterize SVG into Image for PNG export"));
|
|
2938
|
+
};
|
|
2857
2939
|
img.src = url;
|
|
2858
2940
|
});
|
|
2859
2941
|
const width = img.naturalWidth || 800;
|
|
@@ -2925,7 +3007,9 @@ var DiagramPresentationController = class {
|
|
|
2925
3007
|
this.diagram.setPlaybackRate(rate);
|
|
2926
3008
|
}
|
|
2927
3009
|
onKeyDown = (e) => {
|
|
2928
|
-
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement)
|
|
3010
|
+
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement || e.target?.isContentEditable) {
|
|
3011
|
+
return;
|
|
3012
|
+
}
|
|
2929
3013
|
switch (e.key) {
|
|
2930
3014
|
case "ArrowRight":
|
|
2931
3015
|
case "PageDown":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markdy/renderer-dom",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.27",
|
|
4
4
|
"description": "Browser renderer for diagram-native animated MarkdyScript architecture diagrams, built on the Web Animations API.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -44,14 +44,14 @@
|
|
|
44
44
|
"access": "public"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@markdy/core": "0.8.
|
|
47
|
+
"@markdy/core": "0.8.27"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"jsdom": "^29.1.1",
|
|
51
51
|
"tsup": "^8.5.1",
|
|
52
52
|
"typescript": "^5.9.3",
|
|
53
53
|
"vitest": "^4.1.7",
|
|
54
|
-
"@markdy/stdlib-systems": "0.8.
|
|
54
|
+
"@markdy/stdlib-systems": "0.8.27"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "tsup",
|