@markdy/renderer-dom 0.7.10 → 0.7.11
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 +204 -2
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -367,6 +367,66 @@ function createActorEl(name, def, assetDefs, assetOverrides) {
|
|
|
367
367
|
el = createFigureEl(def);
|
|
368
368
|
break;
|
|
369
369
|
}
|
|
370
|
+
case "service":
|
|
371
|
+
case "client":
|
|
372
|
+
case "db":
|
|
373
|
+
case "queue": {
|
|
374
|
+
const card = document.createElement("div");
|
|
375
|
+
const label = document.createElement("div");
|
|
376
|
+
label.textContent = def.args[0] ?? "";
|
|
377
|
+
Object.assign(label.style, {
|
|
378
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
379
|
+
fontSize: `${def.size ?? 16}px`,
|
|
380
|
+
fontWeight: "600",
|
|
381
|
+
color: "#e2e8f0",
|
|
382
|
+
textAlign: "center",
|
|
383
|
+
lineHeight: "1.2",
|
|
384
|
+
pointerEvents: "none",
|
|
385
|
+
whiteSpace: "nowrap",
|
|
386
|
+
overflow: "hidden",
|
|
387
|
+
textOverflow: "ellipsis",
|
|
388
|
+
maxWidth: "100%"
|
|
389
|
+
});
|
|
390
|
+
Object.assign(card.style, {
|
|
391
|
+
width: "180px",
|
|
392
|
+
height: "84px",
|
|
393
|
+
boxSizing: "border-box",
|
|
394
|
+
border: "1px solid #475569",
|
|
395
|
+
background: "#0f172a",
|
|
396
|
+
display: "grid",
|
|
397
|
+
placeItems: "center",
|
|
398
|
+
padding: "10px 12px"
|
|
399
|
+
});
|
|
400
|
+
if (def.type === "service") {
|
|
401
|
+
card.style.borderRadius = "12px";
|
|
402
|
+
card.style.background = "linear-gradient(180deg, #1e293b 0%, #0f172a 100%)";
|
|
403
|
+
} else if (def.type === "client") {
|
|
404
|
+
const bar = document.createElement("div");
|
|
405
|
+
Object.assign(bar.style, {
|
|
406
|
+
position: "absolute",
|
|
407
|
+
top: "8px",
|
|
408
|
+
left: "8px",
|
|
409
|
+
right: "8px",
|
|
410
|
+
height: "8px",
|
|
411
|
+
borderRadius: "6px",
|
|
412
|
+
background: "#334155"
|
|
413
|
+
});
|
|
414
|
+
card.style.position = "relative";
|
|
415
|
+
card.style.borderRadius = "10px";
|
|
416
|
+
card.style.paddingTop = "20px";
|
|
417
|
+
card.appendChild(bar);
|
|
418
|
+
} else if (def.type === "db") {
|
|
419
|
+
card.style.borderRadius = "50% / 14%";
|
|
420
|
+
card.style.background = "linear-gradient(180deg, #334155 0%, #0f172a 70%)";
|
|
421
|
+
card.style.boxShadow = "inset 0 10px 0 rgba(226, 232, 240, 0.12)";
|
|
422
|
+
} else if (def.type === "queue") {
|
|
423
|
+
card.style.borderRadius = "8px";
|
|
424
|
+
card.style.boxShadow = "-6px -6px 0 rgba(30, 41, 59, 0.9), -12px -12px 0 rgba(15, 23, 42, 0.9)";
|
|
425
|
+
}
|
|
426
|
+
card.appendChild(label);
|
|
427
|
+
el = card;
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
370
430
|
default: {
|
|
371
431
|
const div = document.createElement("div");
|
|
372
432
|
div.style.width = "100px";
|
|
@@ -437,7 +497,22 @@ function buildAnimations(ast, actorEls, scene, assetOverrides, faceSwaps) {
|
|
|
437
497
|
const el = actorEls.get(ev.actor);
|
|
438
498
|
const s = states.get(ev.actor);
|
|
439
499
|
if (!el || !s) continue;
|
|
440
|
-
buildAction(
|
|
500
|
+
buildAction(
|
|
501
|
+
ev,
|
|
502
|
+
el,
|
|
503
|
+
s,
|
|
504
|
+
baseOpts,
|
|
505
|
+
delayMs,
|
|
506
|
+
durMs,
|
|
507
|
+
ast,
|
|
508
|
+
states,
|
|
509
|
+
actorEls,
|
|
510
|
+
scene,
|
|
511
|
+
assetOverrides,
|
|
512
|
+
faceSwaps,
|
|
513
|
+
anims,
|
|
514
|
+
txFor(ev.actor)
|
|
515
|
+
);
|
|
441
516
|
}
|
|
442
517
|
return anims;
|
|
443
518
|
}
|
|
@@ -541,8 +616,135 @@ function buildCameraAction(ev, scene, ast, baseOpts, anims, cameraState) {
|
|
|
541
616
|
break;
|
|
542
617
|
}
|
|
543
618
|
}
|
|
544
|
-
|
|
619
|
+
var FLOW_STROKE_BY_ACTION = {
|
|
620
|
+
request: "#38bdf8",
|
|
621
|
+
response: "#a78bfa",
|
|
622
|
+
emit: "#f59e0b"
|
|
623
|
+
};
|
|
624
|
+
function actorSizeByType(type) {
|
|
625
|
+
switch (type) {
|
|
626
|
+
case "service":
|
|
627
|
+
case "client":
|
|
628
|
+
case "db":
|
|
629
|
+
case "queue":
|
|
630
|
+
return { width: 180, height: 84 };
|
|
631
|
+
case "box":
|
|
632
|
+
return { width: 100, height: 100 };
|
|
633
|
+
case "caption":
|
|
634
|
+
return { width: 260, height: 56 };
|
|
635
|
+
case "figure":
|
|
636
|
+
return { width: 120, height: 170 };
|
|
637
|
+
default:
|
|
638
|
+
return { width: 140, height: 42 };
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
function actorCenter(state, actorType) {
|
|
642
|
+
const { width, height } = actorSizeByType(actorType);
|
|
643
|
+
return {
|
|
644
|
+
x: state.x + width / 2,
|
|
645
|
+
y: state.y + height / 2
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
function ensureEdgeLayer(scene) {
|
|
649
|
+
const existing = scene.querySelector("svg[data-markdy-edge-layer='1']");
|
|
650
|
+
if (existing) return existing;
|
|
651
|
+
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
652
|
+
svg.setAttribute("data-markdy-edge-layer", "1");
|
|
653
|
+
Object.assign(svg.style, {
|
|
654
|
+
position: "absolute",
|
|
655
|
+
inset: "0",
|
|
656
|
+
width: "100%",
|
|
657
|
+
height: "100%",
|
|
658
|
+
overflow: "visible",
|
|
659
|
+
pointerEvents: "none",
|
|
660
|
+
zIndex: "95"
|
|
661
|
+
});
|
|
662
|
+
scene.appendChild(svg);
|
|
663
|
+
return svg;
|
|
664
|
+
}
|
|
665
|
+
function renderFlowEdge(ev, sourceState, targetState, sourceType, targetType, scene, baseOpts, anims) {
|
|
666
|
+
const styleToken = String(ev.params.style ?? "");
|
|
667
|
+
const isDashed = styleToken === "dashed" || styleToken === "fire_and_forget" || ev.action === "response";
|
|
668
|
+
const stroke = FLOW_STROKE_BY_ACTION[ev.action] ?? "#38bdf8";
|
|
669
|
+
const source = actorCenter(sourceState, sourceType);
|
|
670
|
+
const target = actorCenter(targetState, targetType);
|
|
671
|
+
const dx = target.x - source.x;
|
|
672
|
+
const dy = target.y - source.y;
|
|
673
|
+
const length = Math.max(1, Math.hypot(dx, dy));
|
|
674
|
+
const mx = source.x + dx / 2;
|
|
675
|
+
const my = source.y + dy / 2;
|
|
676
|
+
const pathD = `M ${source.x} ${source.y} L ${target.x} ${target.y}`;
|
|
677
|
+
const svg = ensureEdgeLayer(scene);
|
|
678
|
+
const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
|
|
679
|
+
group.setAttribute("data-markdy-flow-edge", "1");
|
|
680
|
+
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
|
681
|
+
path.setAttribute("d", pathD);
|
|
682
|
+
path.setAttribute("fill", "none");
|
|
683
|
+
path.setAttribute("stroke", stroke);
|
|
684
|
+
path.setAttribute("stroke-width", "2.5");
|
|
685
|
+
path.style.strokeDasharray = isDashed ? "8 6" : `${length}`;
|
|
686
|
+
path.style.strokeDashoffset = `${length}`;
|
|
687
|
+
group.appendChild(path);
|
|
688
|
+
const marker = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
|
689
|
+
marker.setAttribute("r", "3");
|
|
690
|
+
marker.setAttribute("fill", stroke);
|
|
691
|
+
marker.style.offsetPath = `path('${pathD}')`;
|
|
692
|
+
marker.style.offsetDistance = "0%";
|
|
693
|
+
marker.style.opacity = "0";
|
|
694
|
+
group.appendChild(marker);
|
|
695
|
+
const labelRaw = String(ev.params.label ?? "");
|
|
696
|
+
if (labelRaw) {
|
|
697
|
+
const label = labelRaw.length > 28 ? `${labelRaw.slice(0, 27)}\u2026` : labelRaw;
|
|
698
|
+
const labelEl = document.createElementNS("http://www.w3.org/2000/svg", "text");
|
|
699
|
+
labelEl.setAttribute("x", `${mx}`);
|
|
700
|
+
labelEl.setAttribute("y", `${my - 8}`);
|
|
701
|
+
labelEl.setAttribute("text-anchor", "middle");
|
|
702
|
+
labelEl.setAttribute("font-size", "12");
|
|
703
|
+
labelEl.setAttribute("fill", "#cbd5e1");
|
|
704
|
+
labelEl.textContent = label;
|
|
705
|
+
labelEl.setAttribute("data-full-label", labelRaw);
|
|
706
|
+
group.appendChild(labelEl);
|
|
707
|
+
}
|
|
708
|
+
svg.appendChild(group);
|
|
709
|
+
anims.push(path.animate([{ strokeDashoffset: length }, { strokeDashoffset: 0 }], baseOpts));
|
|
710
|
+
anims.push(
|
|
711
|
+
marker.animate(
|
|
712
|
+
[{ offsetDistance: "0%", opacity: 1 }, { offsetDistance: "100%", opacity: 1 }],
|
|
713
|
+
baseOpts
|
|
714
|
+
)
|
|
715
|
+
);
|
|
716
|
+
const fadeOutDelay = Number(baseOpts.delay ?? 0) + Number(baseOpts.duration ?? 0);
|
|
717
|
+
anims.push(
|
|
718
|
+
group.animate([{ opacity: 1 }, { opacity: 0 }], {
|
|
719
|
+
delay: fadeOutDelay,
|
|
720
|
+
duration: 140,
|
|
721
|
+
fill: "forwards"
|
|
722
|
+
})
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
function buildAction(ev, el, s, baseOpts, delayMs, durMs, ast, states, actorEls, scene, assetOverrides, faceSwaps, anims, txFn) {
|
|
545
726
|
switch (ev.action) {
|
|
727
|
+
case "request":
|
|
728
|
+
case "response":
|
|
729
|
+
case "emit": {
|
|
730
|
+
const targetActorName = String(ev.params.to ?? "");
|
|
731
|
+
if (!targetActorName) break;
|
|
732
|
+
const targetState = states.get(targetActorName);
|
|
733
|
+
if (!targetState) break;
|
|
734
|
+
const sourceType = ast.actors[ev.actor]?.type ?? "box";
|
|
735
|
+
const targetType = ast.actors[targetActorName]?.type ?? "box";
|
|
736
|
+
renderFlowEdge(
|
|
737
|
+
ev,
|
|
738
|
+
s,
|
|
739
|
+
targetState,
|
|
740
|
+
sourceType,
|
|
741
|
+
targetType,
|
|
742
|
+
scene,
|
|
743
|
+
baseOpts,
|
|
744
|
+
anims
|
|
745
|
+
);
|
|
746
|
+
break;
|
|
747
|
+
}
|
|
546
748
|
// ── move ────────────────────────────────────────────────────────────────
|
|
547
749
|
case "move": {
|
|
548
750
|
const toArr = ev.params.to;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markdy/renderer-dom",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.11",
|
|
4
4
|
"description": "Web Animations API renderer for MarkdyScript scenes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@markdy/core": "0.7.
|
|
46
|
+
"@markdy/core": "0.7.11"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"jsdom": "^29.1.1",
|