@spectratools/graphic-designer-cli 0.12.3 → 0.14.1
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/cli.js +316 -5
- package/dist/index.d.ts +2 -2
- package/dist/index.js +316 -5
- package/dist/qa.d.ts +1 -1
- package/dist/qa.js +49 -3
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +316 -5
- package/dist/{spec.schema-BkbcnVcm.d.ts → spec.schema-De-IkUjn.d.ts} +584 -26
- package/dist/spec.schema.d.ts +1 -1
- package/dist/spec.schema.js +49 -3
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -920,6 +920,27 @@ var drawTextRowSchema = z2.object({
|
|
|
920
920
|
defaultColor: colorHexSchema2.default("#FFFFFF"),
|
|
921
921
|
opacity: z2.number().min(0).max(1).default(1)
|
|
922
922
|
}).strict();
|
|
923
|
+
var drawStatsBarItemSchema = z2.object({
|
|
924
|
+
value: z2.string().min(1).max(50),
|
|
925
|
+
label: z2.string().min(1).max(100)
|
|
926
|
+
}).strict();
|
|
927
|
+
var drawStatsBarSchema = z2.object({
|
|
928
|
+
type: z2.literal("stats-bar"),
|
|
929
|
+
y: z2.number().describe("Vertical position of the stats bar"),
|
|
930
|
+
items: z2.array(drawStatsBarItemSchema).min(1).max(8),
|
|
931
|
+
separator: z2.enum(["dot", "pipe", "none"]).default("dot"),
|
|
932
|
+
valueColor: colorHexSchema2.default("#FFFFFF"),
|
|
933
|
+
valueFontSize: z2.number().min(8).max(72).default(18),
|
|
934
|
+
valueFontWeight: z2.number().int().min(100).max(900).default(700),
|
|
935
|
+
valueFontFamily: drawFontFamilySchema.default("mono"),
|
|
936
|
+
labelColor: colorHexSchema2.default("#AAAAAA"),
|
|
937
|
+
labelFontSize: z2.number().min(8).max(72).default(14),
|
|
938
|
+
labelFontWeight: z2.number().int().min(100).max(900).default(400),
|
|
939
|
+
labelFontFamily: drawFontFamilySchema.default("body"),
|
|
940
|
+
separatorColor: colorHexSchema2.default("#666666"),
|
|
941
|
+
gap: z2.number().min(0).max(100).default(24),
|
|
942
|
+
opacity: z2.number().min(0).max(1).default(1)
|
|
943
|
+
}).strict();
|
|
923
944
|
var drawCommandSchema = z2.discriminatedUnion("type", [
|
|
924
945
|
drawRectSchema,
|
|
925
946
|
drawCircleSchema,
|
|
@@ -931,7 +952,8 @@ var drawCommandSchema = z2.discriminatedUnion("type", [
|
|
|
931
952
|
drawBadgeSchema,
|
|
932
953
|
drawGradientRectSchema,
|
|
933
954
|
drawGridSchema,
|
|
934
|
-
drawTextRowSchema
|
|
955
|
+
drawTextRowSchema,
|
|
956
|
+
drawStatsBarSchema
|
|
935
957
|
]);
|
|
936
958
|
var defaultCanvas = {
|
|
937
959
|
width: 1200,
|
|
@@ -1132,6 +1154,24 @@ var imageElementSchema = z2.object({
|
|
|
1132
1154
|
fit: z2.enum(["contain", "cover", "fill", "none"]).default("contain"),
|
|
1133
1155
|
borderRadius: z2.number().min(0).default(0)
|
|
1134
1156
|
}).strict();
|
|
1157
|
+
var ringSegmentSchema = z2.object({
|
|
1158
|
+
color: colorHexSchema2
|
|
1159
|
+
}).strict();
|
|
1160
|
+
var ringElementSchema = z2.object({
|
|
1161
|
+
type: z2.literal("ring"),
|
|
1162
|
+
id: z2.string().min(1).max(120),
|
|
1163
|
+
radius: z2.number().min(8).max(512).default(48),
|
|
1164
|
+
strokeWidth: z2.number().min(1).max(32).default(2),
|
|
1165
|
+
label: z2.string().max(100).optional(),
|
|
1166
|
+
labelColor: colorHexSchema2.optional(),
|
|
1167
|
+
labelSize: z2.number().min(8).max(48).default(12),
|
|
1168
|
+
segments: z2.array(ringSegmentSchema).min(1).max(24).default([{ color: "#4A7BF7" }]),
|
|
1169
|
+
glowRadius: z2.number().min(0).max(64).default(0),
|
|
1170
|
+
glowColor: colorHexSchema2.optional(),
|
|
1171
|
+
showCycleArrows: z2.boolean().default(false),
|
|
1172
|
+
fill: colorHexSchema2.optional(),
|
|
1173
|
+
fillOpacity: z2.number().min(0).max(1).default(0.05)
|
|
1174
|
+
}).strict();
|
|
1135
1175
|
var elementSchema = z2.discriminatedUnion("type", [
|
|
1136
1176
|
cardElementSchema,
|
|
1137
1177
|
flowNodeElementSchema,
|
|
@@ -1140,7 +1180,8 @@ var elementSchema = z2.discriminatedUnion("type", [
|
|
|
1140
1180
|
terminalElementSchema,
|
|
1141
1181
|
textElementSchema,
|
|
1142
1182
|
shapeElementSchema,
|
|
1143
|
-
imageElementSchema
|
|
1183
|
+
imageElementSchema,
|
|
1184
|
+
ringElementSchema
|
|
1144
1185
|
]);
|
|
1145
1186
|
var diagramCenterSchema = z2.object({
|
|
1146
1187
|
x: z2.number(),
|
|
@@ -1261,8 +1302,13 @@ var decoratorSchema = z2.discriminatedUnion("type", [
|
|
|
1261
1302
|
}).strict(),
|
|
1262
1303
|
z2.object({
|
|
1263
1304
|
type: z2.literal("vignette"),
|
|
1305
|
+
mode: z2.enum(["radial", "edge"]).default("radial"),
|
|
1264
1306
|
intensity: z2.number().min(0).max(1).default(0.3),
|
|
1265
|
-
color: colorHexSchema2.default("#000000")
|
|
1307
|
+
color: colorHexSchema2.default("#000000"),
|
|
1308
|
+
edgeTopHeight: z2.number().min(0).max(200).default(35),
|
|
1309
|
+
edgeBottomHeight: z2.number().min(0).max(200).default(55),
|
|
1310
|
+
edgeTopOpacity: z2.number().min(0).max(1).default(0.3),
|
|
1311
|
+
edgeBottomOpacity: z2.number().min(0).max(1).default(0.4)
|
|
1266
1312
|
}).strict(),
|
|
1267
1313
|
z2.object({
|
|
1268
1314
|
type: z2.literal("gradient-overlay"),
|
|
@@ -2069,6 +2115,8 @@ function estimateElementHeight(element) {
|
|
|
2069
2115
|
return 130;
|
|
2070
2116
|
case "image":
|
|
2071
2117
|
return 220;
|
|
2118
|
+
case "ring":
|
|
2119
|
+
return element.radius * 2 + element.glowRadius * 2 + 16;
|
|
2072
2120
|
case "connection":
|
|
2073
2121
|
return 0;
|
|
2074
2122
|
}
|
|
@@ -2089,6 +2137,8 @@ function estimateElementWidth(element) {
|
|
|
2089
2137
|
return 280;
|
|
2090
2138
|
case "image":
|
|
2091
2139
|
return 320;
|
|
2140
|
+
case "ring":
|
|
2141
|
+
return element.radius * 2 + element.glowRadius * 2 + 16;
|
|
2092
2142
|
case "connection":
|
|
2093
2143
|
return 0;
|
|
2094
2144
|
}
|
|
@@ -2703,6 +2753,30 @@ function drawRainbowRule(ctx, x, y, width, thickness = 2, colors = [...DEFAULT_R
|
|
|
2703
2753
|
ctx.fill();
|
|
2704
2754
|
ctx.restore();
|
|
2705
2755
|
}
|
|
2756
|
+
function drawEdgeVignette(ctx, width, height, color = "#000000", topHeight = 35, bottomHeight = 55, topOpacity = 0.3, bottomOpacity = 0.4) {
|
|
2757
|
+
if (width <= 0 || height <= 0) {
|
|
2758
|
+
return;
|
|
2759
|
+
}
|
|
2760
|
+
if (topHeight > 0 && topOpacity > 0) {
|
|
2761
|
+
const topGradient = ctx.createLinearGradient(0, 0, 0, topHeight);
|
|
2762
|
+
topGradient.addColorStop(0, withAlpha2(color, clamp01(topOpacity)));
|
|
2763
|
+
topGradient.addColorStop(1, withAlpha2(color, 0));
|
|
2764
|
+
ctx.save();
|
|
2765
|
+
ctx.fillStyle = topGradient;
|
|
2766
|
+
ctx.fillRect(0, 0, width, topHeight);
|
|
2767
|
+
ctx.restore();
|
|
2768
|
+
}
|
|
2769
|
+
if (bottomHeight > 0 && bottomOpacity > 0) {
|
|
2770
|
+
const bottomY = height - bottomHeight;
|
|
2771
|
+
const bottomGradient = ctx.createLinearGradient(0, bottomY, 0, height);
|
|
2772
|
+
bottomGradient.addColorStop(0, withAlpha2(color, 0));
|
|
2773
|
+
bottomGradient.addColorStop(1, withAlpha2(color, clamp01(bottomOpacity)));
|
|
2774
|
+
ctx.save();
|
|
2775
|
+
ctx.fillStyle = bottomGradient;
|
|
2776
|
+
ctx.fillRect(0, bottomY, width, bottomHeight);
|
|
2777
|
+
ctx.restore();
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2706
2780
|
function drawVignette(ctx, width, height, intensity = 0.3, color = "#000000") {
|
|
2707
2781
|
if (width <= 0 || height <= 0 || intensity <= 0) {
|
|
2708
2782
|
return;
|
|
@@ -4553,10 +4627,118 @@ function renderDrawCommands(ctx, commands, theme) {
|
|
|
4553
4627
|
});
|
|
4554
4628
|
break;
|
|
4555
4629
|
}
|
|
4630
|
+
case "stats-bar": {
|
|
4631
|
+
const barRect = renderStatsBar(ctx, command, theme);
|
|
4632
|
+
rendered.push({
|
|
4633
|
+
id,
|
|
4634
|
+
kind: "draw",
|
|
4635
|
+
bounds: barRect,
|
|
4636
|
+
foregroundColor: command.valueColor,
|
|
4637
|
+
backgroundColor: theme.background
|
|
4638
|
+
});
|
|
4639
|
+
break;
|
|
4640
|
+
}
|
|
4556
4641
|
}
|
|
4557
4642
|
}
|
|
4558
4643
|
return rendered;
|
|
4559
4644
|
}
|
|
4645
|
+
function renderStatsBar(ctx, command, theme) {
|
|
4646
|
+
const canvasWidth = ctx.canvas.width;
|
|
4647
|
+
const valueFontFamily = resolveDrawFont(theme, command.valueFontFamily);
|
|
4648
|
+
const labelFontFamily = resolveDrawFont(theme, command.labelFontFamily);
|
|
4649
|
+
const spaceWidth = 4;
|
|
4650
|
+
const measuredItems = [];
|
|
4651
|
+
for (const item of command.items) {
|
|
4652
|
+
applyFont(ctx, {
|
|
4653
|
+
size: command.valueFontSize,
|
|
4654
|
+
weight: command.valueFontWeight,
|
|
4655
|
+
family: valueFontFamily
|
|
4656
|
+
});
|
|
4657
|
+
const valueWidth = ctx.measureText(item.value).width;
|
|
4658
|
+
applyFont(ctx, {
|
|
4659
|
+
size: command.labelFontSize,
|
|
4660
|
+
weight: command.labelFontWeight,
|
|
4661
|
+
family: labelFontFamily
|
|
4662
|
+
});
|
|
4663
|
+
const labelWidth = ctx.measureText(item.label).width;
|
|
4664
|
+
measuredItems.push({
|
|
4665
|
+
valueWidth,
|
|
4666
|
+
labelWidth,
|
|
4667
|
+
totalWidth: valueWidth + spaceWidth + labelWidth
|
|
4668
|
+
});
|
|
4669
|
+
}
|
|
4670
|
+
let separatorWidth = 0;
|
|
4671
|
+
let separatorText = "";
|
|
4672
|
+
if (command.separator !== "none" && command.items.length > 1) {
|
|
4673
|
+
separatorText = command.separator === "dot" ? "\xB7" : "|";
|
|
4674
|
+
const sepFontSize = Math.max(command.valueFontSize, command.labelFontSize);
|
|
4675
|
+
applyFont(ctx, { size: sepFontSize, weight: 400, family: labelFontFamily });
|
|
4676
|
+
separatorWidth = ctx.measureText(separatorText).width;
|
|
4677
|
+
}
|
|
4678
|
+
const itemsWidth = measuredItems.reduce((sum, m) => sum + m.totalWidth, 0);
|
|
4679
|
+
const gapCount = command.items.length - 1;
|
|
4680
|
+
const totalWidth = itemsWidth + gapCount * (command.gap + separatorWidth);
|
|
4681
|
+
let cursorX = (canvasWidth - totalWidth) / 2;
|
|
4682
|
+
const startX = cursorX;
|
|
4683
|
+
applyFont(ctx, {
|
|
4684
|
+
size: command.valueFontSize,
|
|
4685
|
+
weight: command.valueFontWeight,
|
|
4686
|
+
family: valueFontFamily
|
|
4687
|
+
});
|
|
4688
|
+
const valueMetrics = ctx.measureText("M");
|
|
4689
|
+
const valueAscent = valueMetrics.actualBoundingBoxAscent || command.valueFontSize * 0.75;
|
|
4690
|
+
const valueDescent = valueMetrics.actualBoundingBoxDescent || command.valueFontSize * 0.25;
|
|
4691
|
+
applyFont(ctx, {
|
|
4692
|
+
size: command.labelFontSize,
|
|
4693
|
+
weight: command.labelFontWeight,
|
|
4694
|
+
family: labelFontFamily
|
|
4695
|
+
});
|
|
4696
|
+
const labelMetrics = ctx.measureText("M");
|
|
4697
|
+
const labelAscent = labelMetrics.actualBoundingBoxAscent || command.labelFontSize * 0.75;
|
|
4698
|
+
const labelDescent = labelMetrics.actualBoundingBoxDescent || command.labelFontSize * 0.25;
|
|
4699
|
+
const maxAscent = Math.max(valueAscent, labelAscent);
|
|
4700
|
+
const maxDescent = Math.max(valueDescent, labelDescent);
|
|
4701
|
+
withOpacity(ctx, command.opacity, () => {
|
|
4702
|
+
for (let i = 0; i < command.items.length; i++) {
|
|
4703
|
+
const item = command.items[i];
|
|
4704
|
+
const measured = measuredItems[i];
|
|
4705
|
+
applyFont(ctx, {
|
|
4706
|
+
size: command.valueFontSize,
|
|
4707
|
+
weight: command.valueFontWeight,
|
|
4708
|
+
family: valueFontFamily
|
|
4709
|
+
});
|
|
4710
|
+
ctx.fillStyle = command.valueColor;
|
|
4711
|
+
ctx.textAlign = "left";
|
|
4712
|
+
ctx.textBaseline = "alphabetic";
|
|
4713
|
+
ctx.fillText(item.value, cursorX, command.y);
|
|
4714
|
+
cursorX += measured.valueWidth + spaceWidth;
|
|
4715
|
+
applyFont(ctx, {
|
|
4716
|
+
size: command.labelFontSize,
|
|
4717
|
+
weight: command.labelFontWeight,
|
|
4718
|
+
family: labelFontFamily
|
|
4719
|
+
});
|
|
4720
|
+
ctx.fillStyle = command.labelColor;
|
|
4721
|
+
ctx.fillText(item.label, cursorX, command.y);
|
|
4722
|
+
cursorX += measured.labelWidth;
|
|
4723
|
+
if (i < command.items.length - 1 && command.separator !== "none") {
|
|
4724
|
+
const sepFontSize = Math.max(command.valueFontSize, command.labelFontSize);
|
|
4725
|
+
applyFont(ctx, { size: sepFontSize, weight: 400, family: labelFontFamily });
|
|
4726
|
+
ctx.fillStyle = command.separatorColor;
|
|
4727
|
+
ctx.textAlign = "center";
|
|
4728
|
+
ctx.fillText(separatorText, cursorX + command.gap / 2 + separatorWidth / 2, command.y);
|
|
4729
|
+
ctx.textAlign = "left";
|
|
4730
|
+
cursorX += command.gap + separatorWidth;
|
|
4731
|
+
}
|
|
4732
|
+
}
|
|
4733
|
+
});
|
|
4734
|
+
const height = Math.max(1, maxAscent + maxDescent);
|
|
4735
|
+
return {
|
|
4736
|
+
x: startX,
|
|
4737
|
+
y: command.y - maxAscent,
|
|
4738
|
+
width: Math.max(1, totalWidth),
|
|
4739
|
+
height
|
|
4740
|
+
};
|
|
4741
|
+
}
|
|
4560
4742
|
|
|
4561
4743
|
// src/renderers/image.ts
|
|
4562
4744
|
import { loadImage } from "@napi-rs/canvas";
|
|
@@ -4643,6 +4825,110 @@ async function renderImageElement(ctx, image, bounds, theme) {
|
|
|
4643
4825
|
}
|
|
4644
4826
|
}
|
|
4645
4827
|
|
|
4828
|
+
// src/renderers/ring.ts
|
|
4829
|
+
function renderRingElement(ctx, ring, bounds, theme) {
|
|
4830
|
+
const cx = bounds.x + bounds.width / 2;
|
|
4831
|
+
const cy = bounds.y + bounds.height / 2;
|
|
4832
|
+
const { radius, strokeWidth, segments } = ring;
|
|
4833
|
+
if (ring.glowRadius > 0) {
|
|
4834
|
+
const glowColor = ring.glowColor ?? segments[0].color;
|
|
4835
|
+
ctx.save();
|
|
4836
|
+
ctx.globalAlpha = 0.15;
|
|
4837
|
+
ctx.beginPath();
|
|
4838
|
+
ctx.arc(cx, cy, radius + ring.glowRadius, 0, Math.PI * 2);
|
|
4839
|
+
ctx.fillStyle = glowColor;
|
|
4840
|
+
ctx.fill();
|
|
4841
|
+
ctx.restore();
|
|
4842
|
+
}
|
|
4843
|
+
if (ring.fill || ring.fillOpacity > 0) {
|
|
4844
|
+
const fillColor = ring.fill ?? segments[0].color;
|
|
4845
|
+
ctx.save();
|
|
4846
|
+
ctx.globalAlpha = ring.fillOpacity;
|
|
4847
|
+
ctx.beginPath();
|
|
4848
|
+
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
|
|
4849
|
+
ctx.fillStyle = fillColor;
|
|
4850
|
+
ctx.fill();
|
|
4851
|
+
ctx.restore();
|
|
4852
|
+
}
|
|
4853
|
+
ctx.save();
|
|
4854
|
+
ctx.globalAlpha = 0.2;
|
|
4855
|
+
ctx.beginPath();
|
|
4856
|
+
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
|
|
4857
|
+
ctx.strokeStyle = theme.border;
|
|
4858
|
+
ctx.lineWidth = strokeWidth;
|
|
4859
|
+
ctx.stroke();
|
|
4860
|
+
ctx.restore();
|
|
4861
|
+
const segmentAngle = 2 * Math.PI / segments.length;
|
|
4862
|
+
for (let i = 0; i < segments.length; i++) {
|
|
4863
|
+
const startAngle = i * segmentAngle - Math.PI / 2;
|
|
4864
|
+
ctx.beginPath();
|
|
4865
|
+
ctx.arc(cx, cy, radius, startAngle, startAngle + segmentAngle);
|
|
4866
|
+
ctx.strokeStyle = segments[i].color;
|
|
4867
|
+
ctx.lineWidth = strokeWidth;
|
|
4868
|
+
ctx.stroke();
|
|
4869
|
+
}
|
|
4870
|
+
if (ring.showCycleArrows) {
|
|
4871
|
+
const arrowArcRadius = radius + strokeWidth + 4;
|
|
4872
|
+
const arrowColor = segments[0].color;
|
|
4873
|
+
const numArrows = Math.min(segments.length, 4);
|
|
4874
|
+
const arrowSpacing = 2 * Math.PI / numArrows;
|
|
4875
|
+
for (let i = 0; i < numArrows; i++) {
|
|
4876
|
+
const baseAngle = i * arrowSpacing - Math.PI / 2;
|
|
4877
|
+
const arcStart = baseAngle + 0.15;
|
|
4878
|
+
const arcEnd = baseAngle + arrowSpacing - 0.15;
|
|
4879
|
+
ctx.beginPath();
|
|
4880
|
+
ctx.arc(cx, cy, arrowArcRadius, arcStart, arcEnd);
|
|
4881
|
+
ctx.strokeStyle = arrowColor;
|
|
4882
|
+
ctx.lineWidth = Math.max(1, strokeWidth * 0.6);
|
|
4883
|
+
ctx.stroke();
|
|
4884
|
+
const headAngle = arcEnd;
|
|
4885
|
+
const headX = cx + arrowArcRadius * Math.cos(headAngle);
|
|
4886
|
+
const headY = cy + arrowArcRadius * Math.sin(headAngle);
|
|
4887
|
+
const tangentAngle = headAngle + Math.PI / 2;
|
|
4888
|
+
const headSize = Math.max(4, strokeWidth * 2);
|
|
4889
|
+
ctx.beginPath();
|
|
4890
|
+
ctx.moveTo(headX, headY);
|
|
4891
|
+
ctx.lineTo(
|
|
4892
|
+
headX - headSize * Math.cos(tangentAngle - 0.4),
|
|
4893
|
+
headY - headSize * Math.sin(tangentAngle - 0.4)
|
|
4894
|
+
);
|
|
4895
|
+
ctx.lineTo(
|
|
4896
|
+
headX - headSize * Math.cos(tangentAngle + 0.4),
|
|
4897
|
+
headY - headSize * Math.sin(tangentAngle + 0.4)
|
|
4898
|
+
);
|
|
4899
|
+
ctx.closePath();
|
|
4900
|
+
ctx.fillStyle = arrowColor;
|
|
4901
|
+
ctx.fill();
|
|
4902
|
+
}
|
|
4903
|
+
}
|
|
4904
|
+
if (ring.label) {
|
|
4905
|
+
const labelColor = ring.labelColor ?? theme.text;
|
|
4906
|
+
const labelSize = ring.labelSize;
|
|
4907
|
+
const bodyFont = resolveFont(theme.fonts.body, "body");
|
|
4908
|
+
applyFont(ctx, { size: labelSize, weight: 500, family: bodyFont });
|
|
4909
|
+
ctx.fillStyle = labelColor;
|
|
4910
|
+
ctx.textAlign = "center";
|
|
4911
|
+
ctx.textBaseline = "middle";
|
|
4912
|
+
const lines = ring.label.split("\\n");
|
|
4913
|
+
const lineHeight = labelSize * 1.3;
|
|
4914
|
+
const totalHeight = lines.length * lineHeight;
|
|
4915
|
+
const startY = cy - totalHeight / 2 + lineHeight / 2;
|
|
4916
|
+
for (let i = 0; i < lines.length; i++) {
|
|
4917
|
+
ctx.fillText(lines[i], cx, startY + i * lineHeight);
|
|
4918
|
+
}
|
|
4919
|
+
ctx.textAlign = "left";
|
|
4920
|
+
ctx.textBaseline = "alphabetic";
|
|
4921
|
+
}
|
|
4922
|
+
return [
|
|
4923
|
+
{
|
|
4924
|
+
id: `ring-${ring.id}`,
|
|
4925
|
+
kind: "shape",
|
|
4926
|
+
bounds,
|
|
4927
|
+
foregroundColor: segments[0].color
|
|
4928
|
+
}
|
|
4929
|
+
];
|
|
4930
|
+
}
|
|
4931
|
+
|
|
4646
4932
|
// src/renderers/shape.ts
|
|
4647
4933
|
function renderShapeElement(ctx, shape, bounds, theme) {
|
|
4648
4934
|
const fill = shape.fill ?? theme.surfaceMuted;
|
|
@@ -5078,7 +5364,16 @@ async function renderDesign(input, options = {}) {
|
|
|
5078
5364
|
const deferredVignettes = [];
|
|
5079
5365
|
for (const [index, decorator] of spec.decorators.entries()) {
|
|
5080
5366
|
if (decorator.type === "vignette") {
|
|
5081
|
-
deferredVignettes.push({
|
|
5367
|
+
deferredVignettes.push({
|
|
5368
|
+
index,
|
|
5369
|
+
mode: decorator.mode,
|
|
5370
|
+
intensity: decorator.intensity,
|
|
5371
|
+
color: decorator.color,
|
|
5372
|
+
edgeTopHeight: decorator.edgeTopHeight,
|
|
5373
|
+
edgeBottomHeight: decorator.edgeBottomHeight,
|
|
5374
|
+
edgeTopOpacity: decorator.edgeTopOpacity,
|
|
5375
|
+
edgeBottomOpacity: decorator.edgeBottomOpacity
|
|
5376
|
+
});
|
|
5082
5377
|
continue;
|
|
5083
5378
|
}
|
|
5084
5379
|
if (decorator.type === "gradient-overlay") {
|
|
@@ -5151,6 +5446,9 @@ async function renderDesign(input, options = {}) {
|
|
|
5151
5446
|
case "image":
|
|
5152
5447
|
elements.push(...await renderImageElement(ctx, element, rect, theme));
|
|
5153
5448
|
break;
|
|
5449
|
+
case "ring":
|
|
5450
|
+
elements.push(...renderRingElement(ctx, element, rect, theme));
|
|
5451
|
+
break;
|
|
5154
5452
|
}
|
|
5155
5453
|
}
|
|
5156
5454
|
const nodeBounds = spec.elements.filter((element) => element.type !== "connection").map((element) => elementRects.get(element.id)).filter((rect) => rect != null);
|
|
@@ -5205,7 +5503,20 @@ async function renderDesign(input, options = {}) {
|
|
|
5205
5503
|
}
|
|
5206
5504
|
elements.push(...renderDrawCommands(ctx, spec.draw, theme));
|
|
5207
5505
|
for (const vignette of deferredVignettes) {
|
|
5208
|
-
|
|
5506
|
+
if (vignette.mode === "edge") {
|
|
5507
|
+
drawEdgeVignette(
|
|
5508
|
+
ctx,
|
|
5509
|
+
spec.canvas.width,
|
|
5510
|
+
spec.canvas.height,
|
|
5511
|
+
vignette.color,
|
|
5512
|
+
vignette.edgeTopHeight,
|
|
5513
|
+
vignette.edgeBottomHeight,
|
|
5514
|
+
vignette.edgeTopOpacity,
|
|
5515
|
+
vignette.edgeBottomOpacity
|
|
5516
|
+
);
|
|
5517
|
+
} else {
|
|
5518
|
+
drawVignette(ctx, spec.canvas.width, spec.canvas.height, vignette.intensity, vignette.color);
|
|
5519
|
+
}
|
|
5209
5520
|
elements.push({
|
|
5210
5521
|
id: `decorator-vignette-${vignette.index}`,
|
|
5211
5522
|
kind: "vignette",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Cli } from 'incur';
|
|
2
|
-
import { T as ThemeInput, D as DesignSpec, a as Rect$1, b as DrawCommand, c as Theme, d as RenderedElement, A as AnchorHint, C as ConnectionElement } from './spec.schema-
|
|
3
|
-
export { e as AutoLayoutConfig, B as BuiltInTheme, f as CardElement, g as CodeBlockElement, h as ConstraintSpec, i as DEFAULT_GENERATOR_VERSION, j as DEFAULT_RAINBOW_COLORS, k as Decorator, l as DesignCardSpec, m as DesignSafeFrame, n as DesignTheme, o as DiagramElement, p as DiagramLayout, q as DiagramSpec, r as DrawArc, s as DrawBadge, t as DrawBezier, u as DrawCircle, v as DrawFontFamily, w as DrawGradientRect, x as DrawLine, y as DrawPath, z as DrawPoint, E as DrawRect, F as DrawShadow, G as DrawText, H as DrawTextRow, I as DrawTextRowSegment, J as Element, K as EllipseLayoutConfig, L as FlowNodeElement, M as Gradient, N as GradientOverlayDecorator, O as GradientSpec, P as GradientStop, Q as GridLayoutConfig, S as ImageElement, U as IterationMeta, V as LayoutConfig, W as LayoutSnapshot, X as ManualLayoutConfig, Y as RainbowRuleDecorator, Z as RenderDesignOptions, R as RenderMetadata, _ as RenderResult, $ as ShapeElement, a0 as StackLayoutConfig, a1 as TerminalElement, a2 as TextElement, a3 as ThemeInput, a4 as VignetteDecorator, a5 as WrittenArtifacts, a6 as builtInThemeBackgrounds, a7 as builtInThemes, a8 as computeSpecHash, a9 as connectionElementSchema, aa as defaultAutoLayout, ab as defaultCanvas, ac as defaultConstraints, ad as defaultGridLayout, ae as defaultLayout, af as defaultStackLayout, ag as defaultTheme, ah as deriveSafeFrame, ai as designSpecSchema, aj as diagramElementSchema, ak as diagramLayoutSchema, al as diagramSpecSchema, am as drawGradientRect, an as drawRainbowRule, ao as drawVignette, ap as flowNodeElementSchema, aq as inferLayout, ar as inferSidecarPath, as as parseDesignSpec, at as parseDiagramSpec, au as renderDesign, av as resolveTheme, aw as writeRenderArtifacts } from './spec.schema-
|
|
2
|
+
import { T as ThemeInput, D as DesignSpec, a as Rect$1, b as DrawCommand, c as Theme, d as RenderedElement, A as AnchorHint, C as ConnectionElement } from './spec.schema-De-IkUjn.js';
|
|
3
|
+
export { e as AutoLayoutConfig, B as BuiltInTheme, f as CardElement, g as CodeBlockElement, h as ConstraintSpec, i as DEFAULT_GENERATOR_VERSION, j as DEFAULT_RAINBOW_COLORS, k as Decorator, l as DesignCardSpec, m as DesignSafeFrame, n as DesignTheme, o as DiagramElement, p as DiagramLayout, q as DiagramSpec, r as DrawArc, s as DrawBadge, t as DrawBezier, u as DrawCircle, v as DrawFontFamily, w as DrawGradientRect, x as DrawLine, y as DrawPath, z as DrawPoint, E as DrawRect, F as DrawShadow, G as DrawText, H as DrawTextRow, I as DrawTextRowSegment, J as Element, K as EllipseLayoutConfig, L as FlowNodeElement, M as Gradient, N as GradientOverlayDecorator, O as GradientSpec, P as GradientStop, Q as GridLayoutConfig, S as ImageElement, U as IterationMeta, V as LayoutConfig, W as LayoutSnapshot, X as ManualLayoutConfig, Y as RainbowRuleDecorator, Z as RenderDesignOptions, R as RenderMetadata, _ as RenderResult, $ as ShapeElement, a0 as StackLayoutConfig, a1 as TerminalElement, a2 as TextElement, a3 as ThemeInput, a4 as VignetteDecorator, a5 as WrittenArtifacts, a6 as builtInThemeBackgrounds, a7 as builtInThemes, a8 as computeSpecHash, a9 as connectionElementSchema, aa as defaultAutoLayout, ab as defaultCanvas, ac as defaultConstraints, ad as defaultGridLayout, ae as defaultLayout, af as defaultStackLayout, ag as defaultTheme, ah as deriveSafeFrame, ai as designSpecSchema, aj as diagramElementSchema, ak as diagramLayoutSchema, al as diagramSpecSchema, am as drawGradientRect, an as drawRainbowRule, ao as drawVignette, ap as flowNodeElementSchema, aq as inferLayout, ar as inferSidecarPath, as as parseDesignSpec, at as parseDiagramSpec, au as renderDesign, av as resolveTheme, aw as writeRenderArtifacts } from './spec.schema-De-IkUjn.js';
|
|
4
4
|
import { SKRSContext2D } from '@napi-rs/canvas';
|
|
5
5
|
export { QaIssue, QaReferenceResult, QaReport, QaSeverity, readMetadata, runQa } from './qa.js';
|
|
6
6
|
import { Highlighter } from 'shiki';
|