sketchmark 1.3.2 → 1.3.5

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 CHANGED
@@ -598,6 +598,12 @@ function parse(src, options = {}) {
598
598
  id,
599
599
  shape,
600
600
  label: props.label || "",
601
+ ...(props["label-dx"] !== undefined
602
+ ? { labelDx: parseFloat(props["label-dx"]) }
603
+ : {}),
604
+ ...(props["label-dy"] !== undefined
605
+ ? { labelDy: parseFloat(props["label-dy"]) }
606
+ : {}),
601
607
  ...(props.width ? { width: parseFloat(props.width) } : {}),
602
608
  ...(props.height ? { height: parseFloat(props.height) } : {}),
603
609
  ...(props.x ? { x: parseFloat(props.x) } : {}),
@@ -638,6 +644,12 @@ function parse(src, options = {}) {
638
644
  id,
639
645
  shape: "note",
640
646
  label: (props.label ?? "").replace(/\\n/g, "\n"),
647
+ ...(props["label-dx"] !== undefined
648
+ ? { labelDx: parseFloat(props["label-dx"]) }
649
+ : {}),
650
+ ...(props["label-dy"] !== undefined
651
+ ? { labelDy: parseFloat(props["label-dy"]) }
652
+ : {}),
641
653
  theme: props.theme,
642
654
  ...(meta ? { meta } : {}),
643
655
  style: propsToStyle(props),
@@ -686,6 +698,8 @@ function parse(src, options = {}) {
686
698
  kind: "group",
687
699
  id,
688
700
  label: props.label ?? "",
701
+ labelDx: props["label-dx"] !== undefined ? parseFloat(props["label-dx"]) : undefined,
702
+ labelDy: props["label-dy"] !== undefined ? parseFloat(props["label-dy"]) : undefined,
689
703
  children: [],
690
704
  layout: props.layout,
691
705
  columns: props.columns !== undefined ? parseInt(props.columns, 10) : undefined,
@@ -730,6 +744,8 @@ function parse(src, options = {}) {
730
744
  to: toTok.value,
731
745
  connector: connector,
732
746
  label: props.label,
747
+ labelDx: props["label-dx"] !== undefined ? parseFloat(props["label-dx"]) : undefined,
748
+ labelDy: props["label-dy"] !== undefined ? parseFloat(props["label-dy"]) : undefined,
733
749
  fromAnchor: props["anchor-from"],
734
750
  toAnchor: props["anchor-to"],
735
751
  dashed,
@@ -1231,6 +1247,7 @@ const LAYOUT = {
1231
1247
  const NODE = {
1232
1248
  minW: 90, // minimum auto-sized node width (px)
1233
1249
  maxW: 300, // maximum auto-sized node width (px)
1250
+ mediaLabelH: 20, // reserved bottom strip for icon/image/line labels (px)
1234
1251
  basePad: 26, // base padding added to label width (px)
1235
1252
  };
1236
1253
  // ── Shape-specific sizing ──────────────────────────────────
@@ -3554,6 +3571,8 @@ function buildSceneGraph(ast) {
3554
3571
  id: n.id,
3555
3572
  shape: n.shape,
3556
3573
  label: n.label,
3574
+ labelDx: n.labelDx,
3575
+ labelDy: n.labelDy,
3557
3576
  style: { ...ast.styles[n.id], ...themeStyle, ...n.style },
3558
3577
  groupId: nodeParentById.get(n.id),
3559
3578
  width: n.width,
@@ -3579,6 +3598,8 @@ function buildSceneGraph(ast) {
3579
3598
  return {
3580
3599
  id: g.id,
3581
3600
  label: g.label,
3601
+ labelDx: g.labelDx,
3602
+ labelDy: g.labelDy,
3582
3603
  parentId: groupParentById.get(g.id),
3583
3604
  children: g.children,
3584
3605
  layout: (g.layout ?? "column"),
@@ -3656,6 +3677,8 @@ function buildSceneGraph(ast) {
3656
3677
  to: e.to,
3657
3678
  connector: e.connector,
3658
3679
  label: e.label,
3680
+ labelDx: e.labelDx,
3681
+ labelDy: e.labelDy,
3659
3682
  fromAnchor: e.fromAnchor,
3660
3683
  toAnchor: e.toAnchor,
3661
3684
  dashed: e.dashed ?? false,
@@ -3997,10 +4020,25 @@ const textShape = {
3997
4020
  },
3998
4021
  };
3999
4022
 
4023
+ const MEDIA_LABEL_SHAPES = new Set(["icon", "image", "line"]);
4024
+ function usesBottomLabelStrip(shape) {
4025
+ return MEDIA_LABEL_SHAPES.has(shape);
4026
+ }
4027
+ function getBottomLabelStripHeight(node) {
4028
+ return usesBottomLabelStrip(node.shape) && node.label ? NODE.mediaLabelH : 0;
4029
+ }
4030
+ function getBottomLabelContentHeight(node) {
4031
+ return node.h - getBottomLabelStripHeight(node);
4032
+ }
4033
+ function getBottomLabelCenterY(node) {
4034
+ const stripH = getBottomLabelStripHeight(node);
4035
+ return stripH > 0 ? node.y + node.h - stripH / 2 : node.y + node.h / 2;
4036
+ }
4037
+
4000
4038
  const iconShape = {
4001
4039
  size(n, labelW) {
4002
4040
  const iconBase = 48;
4003
- const labelH = n.label ? 20 : 0;
4041
+ const labelH = getBottomLabelStripHeight(n);
4004
4042
  n.w = n.w || Math.max(iconBase, n.label ? labelW : 0);
4005
4043
  n.h = n.h || (iconBase + labelH);
4006
4044
  },
@@ -4013,8 +4051,7 @@ const iconShape = {
4013
4051
  const iconColor = s.color
4014
4052
  ? encodeURIComponent(String(s.color))
4015
4053
  : encodeURIComponent(String(palette.nodeStroke));
4016
- const labelSpace = n.label ? 20 : 0;
4017
- const iconAreaH = n.h - labelSpace;
4054
+ const iconAreaH = getBottomLabelContentHeight(n);
4018
4055
  const iconSize = Math.min(n.w, iconAreaH) - 4;
4019
4056
  const iconUrl = `https://api.iconify.design/${prefix}/${name}.svg?color=${iconColor}&width=${iconSize}&height=${iconSize}`;
4020
4057
  const img = document.createElementNS(SVG_NS, "image");
@@ -4058,8 +4095,7 @@ const iconShape = {
4058
4095
  const iconColor = s.color
4059
4096
  ? encodeURIComponent(String(s.color))
4060
4097
  : encodeURIComponent(String(palette.nodeStroke));
4061
- const iconLabelSpace = n.label ? 20 : 0;
4062
- const iconAreaH = n.h - iconLabelSpace;
4098
+ const iconAreaH = getBottomLabelContentHeight(n);
4063
4099
  const iconSize = Math.min(n.w, iconAreaH) - 4;
4064
4100
  const iconUrl = `https://api.iconify.design/${prefix}/${name}.svg?color=${iconColor}&width=${iconSize}&height=${iconSize}`;
4065
4101
  const img = new Image();
@@ -4102,21 +4138,21 @@ const imageShape = {
4102
4138
  const w = n.w || Math.max(MIN_W, Math.min(MAX_W, labelW));
4103
4139
  n.w = w;
4104
4140
  if (!n.h) {
4141
+ const labelH = getBottomLabelStripHeight(n);
4105
4142
  if (labelW > w) {
4106
4143
  const fontSize = Number(n.style?.fontSize ?? 14);
4107
4144
  const lines = Math.ceil(labelW / (w - 16));
4108
- n.h = Math.max(52, lines * fontSize * 1.5 + 20);
4145
+ n.h = Math.max(52, lines * fontSize * 1.5 + labelH);
4109
4146
  }
4110
4147
  else {
4111
- n.h = 52;
4148
+ n.h = 52 + labelH;
4112
4149
  }
4113
4150
  }
4114
4151
  },
4115
4152
  renderSVG(rc, n, _palette, opts) {
4116
4153
  const s = n.style ?? {};
4117
4154
  if (n.imageUrl) {
4118
- const imgLabelSpace = n.label ? 20 : 0;
4119
- const imgAreaH = n.h - imgLabelSpace;
4155
+ const imgAreaH = getBottomLabelContentHeight(n);
4120
4156
  const img = document.createElementNS(SVG_NS, "image");
4121
4157
  img.setAttribute("href", n.imageUrl);
4122
4158
  img.setAttribute("x", String(n.x + 1));
@@ -4148,8 +4184,7 @@ const imageShape = {
4148
4184
  renderCanvas(rc, ctx, n, _palette, opts) {
4149
4185
  const s = n.style ?? {};
4150
4186
  if (n.imageUrl) {
4151
- const imgLblSpace = n.label ? 20 : 0;
4152
- const imgAreaH = n.h - imgLblSpace;
4187
+ const imgAreaH = getBottomLabelContentHeight(n);
4153
4188
  const img = new Image();
4154
4189
  img.crossOrigin = "anonymous";
4155
4190
  img.onload = () => {
@@ -4326,17 +4361,17 @@ const noteShape = {
4326
4361
 
4327
4362
  const lineShape = {
4328
4363
  size(n, labelW) {
4329
- const labelH = n.label ? 20 : 0;
4364
+ const labelH = getBottomLabelStripHeight(n);
4330
4365
  n.w = n.width ?? Math.max(MIN_W, labelW + 20);
4331
4366
  n.h = n.height ?? (6 + labelH);
4332
4367
  },
4333
4368
  renderSVG(rc, n, _palette, opts) {
4334
- const labelH = n.label ? 20 : 0;
4369
+ const labelH = getBottomLabelStripHeight(n);
4335
4370
  const lineY = n.y + (n.h - labelH) / 2;
4336
4371
  return [rc.line(n.x, lineY, n.x + n.w, lineY, opts)];
4337
4372
  },
4338
4373
  renderCanvas(rc, _ctx, n, _palette, opts) {
4339
- const labelH = n.label ? 20 : 0;
4374
+ const labelH = getBottomLabelStripHeight(n);
4340
4375
  const lineY = n.y + (n.h - labelH) / 2;
4341
4376
  rc.line(n.x, lineY, n.x + n.w, lineY, opts);
4342
4377
  },
@@ -5582,18 +5617,18 @@ function renderRoughChartSVG(rc, c, palette, isDark) {
5582
5617
  stroke: bgStroke, strokeWidth: Number(s.strokeWidth ?? 1.2),
5583
5618
  ...(s.strokeDash ? { strokeLineDash: s.strokeDash } : {}),
5584
5619
  }));
5620
+ const { px, py, pw, ph, titleH, cx, cy } = chartLayout(c);
5585
5621
  // Title
5586
5622
  if (c.label) {
5587
- cg.appendChild(mkT(c.label, c.x + c.w / 2, c.y + 14, cFontSize, cFontWeight, lc, 'middle', cFont));
5623
+ cg.appendChild(mkT(c.label, c.x + c.w / 2, c.y + titleH / 2 + 2, cFontSize, cFontWeight, lc, 'middle', cFont));
5588
5624
  }
5589
- const { px, py, pw, ph, cx, cy } = chartLayout(c);
5590
5625
  // ── Pie / Donut ──────────────────────────────────────────
5591
5626
  if (c.chartType === 'pie' || c.chartType === 'donut') {
5592
5627
  const { segments, total } = parsePie(c.data);
5593
- const r = Math.min(c.w * 0.38, (c.h - (c.label ? 24 : 8)) * 0.44);
5628
+ const r = Math.min(c.w * 0.38, (c.h - titleH) * 0.44);
5594
5629
  const ir = c.chartType === 'donut' ? r * 0.48 : 0;
5595
5630
  const legendX = c.x + 8;
5596
- const legendY = c.y + (c.label ? 28 : 12);
5631
+ const legendY = c.y + titleH + 4;
5597
5632
  let angle = -Math.PI / 2;
5598
5633
  for (const seg of segments) {
5599
5634
  const sweep = (seg.value / total) * Math.PI * 2;
@@ -5631,7 +5666,7 @@ function renderRoughChartSVG(rc, c, palette, isDark) {
5631
5666
  strokeWidth: 1.2,
5632
5667
  }));
5633
5668
  });
5634
- legend(cg, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + (c.label ? 28 : 12), lc, cFont);
5669
+ legend(cg, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + titleH + 4, lc, cFont);
5635
5670
  return cg;
5636
5671
  }
5637
5672
  // ── Bar / Line / Area ─────────────────────────────────────
@@ -8377,9 +8412,10 @@ function renderToSVG(sg, container, options = {}) {
8377
8412
  }));
8378
8413
  // ── Group label typography ──────────────────────────
8379
8414
  const gTypo = resolveTypography(gs, { fontSize: GROUP_LABEL.fontSize, fontWeight: GROUP_LABEL.fontWeight, textAlign: "left", padding: GROUP_LABEL.padding }, diagramFont, palette.groupLabel);
8380
- const gTextX = computeTextX(gTypo, g.x, g.w);
8415
+ const gTextX = computeTextX(gTypo, g.x, g.w) + (g.labelDx ?? 0);
8416
+ const gTextY = g.y + gTypo.padding + (g.labelDy ?? 0);
8381
8417
  if (g.label) {
8382
- gg.appendChild(mkText(g.label, gTextX, g.y + gTypo.padding, gTypo.fontSize, gTypo.fontWeight, gTypo.textColor, gTypo.textAnchor, gTypo.font, gTypo.letterSpacing));
8418
+ gg.appendChild(mkText(g.label, gTextX, gTextY, gTypo.fontSize, gTypo.fontWeight, gTypo.textColor, gTypo.textAnchor, gTypo.font, gTypo.letterSpacing));
8383
8419
  }
8384
8420
  GL.appendChild(gg);
8385
8421
  }
@@ -8431,8 +8467,8 @@ function renderToSVG(sg, container, options = {}) {
8431
8467
  eg.appendChild(startHead);
8432
8468
  }
8433
8469
  if (e.label) {
8434
- const mx = (x1 + x2) / 2 - ny * EDGE.labelOffset;
8435
- const my = (y1 + y2) / 2 + nx * EDGE.labelOffset;
8470
+ const mx = (x1 + x2) / 2 - ny * EDGE.labelOffset + (e.labelDx ?? 0);
8471
+ const my = (y1 + y2) / 2 + nx * EDGE.labelOffset + (e.labelDy ?? 0);
8436
8472
  const tw = Math.max(e.label.length * 7 + 12, 36);
8437
8473
  const bg = se("rect");
8438
8474
  bg.setAttribute("x", String(mx - tw / 2));
@@ -8500,7 +8536,7 @@ function renderToSVG(sg, container, options = {}) {
8500
8536
  // ── Node / text typography ─────────────────────────
8501
8537
  const isText = n.shape === "text";
8502
8538
  const isNote = n.shape === "note";
8503
- const isMediaShape = n.shape === "icon" || n.shape === "image" || n.shape === "line";
8539
+ const usesBottomStrip = usesBottomLabelStrip(n.shape);
8504
8540
  const typo = resolveTypography(n.style, {
8505
8541
  fontSize: isText ? 13 : isNote ? 12 : 14,
8506
8542
  fontWeight: isText || isNote ? 400 : 500,
@@ -8518,20 +8554,22 @@ function renderToSVG(sg, container, options = {}) {
8518
8554
  : n.x + typo.padding)
8519
8555
  : computeTextX(typo, n.x, n.w);
8520
8556
  const fontStr = buildFontStr(typo.fontSize, typo.fontWeight, typo.font);
8521
- const shouldWrap = !isMediaShape && !n.label.includes('\n');
8557
+ const shouldWrap = !usesBottomStrip && !n.label.includes('\n');
8522
8558
  const innerW = shapeInnerTextWidth(n.shape, n.w, typo.padding);
8523
8559
  const lines = shouldWrap
8524
8560
  ? wrapText(n.label, innerW, typo.fontSize, fontStr)
8525
8561
  : n.label.split('\n');
8526
- const textCY = isMediaShape
8527
- ? n.y + n.h - 10
8562
+ const textCY = usesBottomStrip
8563
+ ? getBottomLabelCenterY(n)
8528
8564
  : isNote
8529
8565
  ? computeTextCY(typo, n.y, n.h, lines.length, FOLD + typo.padding)
8530
8566
  : computeTextCY(typo, n.y, n.h, lines.length);
8567
+ const labelX = textX + (n.labelDx ?? 0);
8568
+ const labelY = textCY + (n.labelDy ?? 0);
8531
8569
  if (n.label) {
8532
8570
  ng.appendChild(lines.length > 1
8533
- ? mkMultilineText(lines, textX, textCY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAnchor, typo.lineHeight, typo.font, typo.letterSpacing)
8534
- : mkText(n.label, textX, textCY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAnchor, typo.font, typo.letterSpacing));
8571
+ ? mkMultilineText(lines, labelX, labelY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAnchor, typo.lineHeight, typo.font, typo.letterSpacing)
8572
+ : mkText(n.label, labelX, labelY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAnchor, typo.font, typo.letterSpacing));
8535
8573
  }
8536
8574
  if (options.interactive) {
8537
8575
  ng.style.cursor = "pointer";
@@ -8845,6 +8883,7 @@ function drawRoughChartCanvas(rc, ctx, c, pal, R) {
8845
8883
  strokeWidth: Number(s.strokeWidth ?? 1.2),
8846
8884
  ...(s.strokeDash ? { strokeLineDash: s.strokeDash } : {}),
8847
8885
  });
8886
+ const { px, py, pw, ph, titleH, cx, cy } = chartLayout(c);
8848
8887
  // Title
8849
8888
  if (c.label) {
8850
8889
  ctx.save();
@@ -8852,17 +8891,16 @@ function drawRoughChartCanvas(rc, ctx, c, pal, R) {
8852
8891
  ctx.fillStyle = lc;
8853
8892
  ctx.textAlign = 'center';
8854
8893
  ctx.textBaseline = 'middle';
8855
- ctx.fillText(c.label, c.x + c.w / 2, c.y + 14);
8894
+ ctx.fillText(c.label, c.x + c.w / 2, c.y + titleH / 2 + 2);
8856
8895
  ctx.restore();
8857
8896
  }
8858
- const { px, py, pw, ph, cx, cy } = chartLayout(c);
8859
8897
  // ── Pie / Donut ──────────────────────────────────────────
8860
8898
  if (c.chartType === 'pie' || c.chartType === 'donut') {
8861
8899
  const { segments, total } = parsePie(c.data);
8862
- const r = Math.min(c.w * 0.38, (c.h - (c.label ? 24 : 8)) * 0.44);
8900
+ const r = Math.min(c.w * 0.38, (c.h - titleH) * 0.44);
8863
8901
  const ir = c.chartType === 'donut' ? r * 0.48 : 0;
8864
8902
  const legendX = c.x + 8;
8865
- const legendY = c.y + (c.label ? 28 : 12);
8903
+ const legendY = c.y + titleH + 4;
8866
8904
  let angle = -Math.PI / 2;
8867
8905
  segments.forEach((seg, i) => {
8868
8906
  const sweep = (seg.value / total) * Math.PI * 2;
@@ -8890,7 +8928,7 @@ function drawRoughChartCanvas(rc, ctx, c, pal, R) {
8890
8928
  strokeWidth: 1.2,
8891
8929
  });
8892
8930
  });
8893
- drawLegend(ctx, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + (c.label ? 28 : 12), lc, cFont);
8931
+ drawLegend(ctx, pts.map(p => p.label), CHART_COLORS, c.x + 8, c.y + titleH + 4, lc, cFont);
8894
8932
  ctx.globalAlpha = 1;
8895
8933
  return;
8896
8934
  }
@@ -9125,8 +9163,9 @@ function renderToCanvas(sg, canvas, options = {}) {
9125
9163
  });
9126
9164
  if (g.label) {
9127
9165
  const gTypo = resolveTypography(gs, { fontSize: GROUP_LABEL.fontSize, fontWeight: GROUP_LABEL.fontWeight, textAlign: "left", padding: GROUP_LABEL.padding }, diagramFont, palette.groupLabel);
9128
- const gTextX = computeTextX(gTypo, g.x, g.w);
9129
- drawText(ctx, g.label, gTextX, g.y + gTypo.padding + 2, gTypo.fontSize, gTypo.fontWeight, gTypo.textColor, gTypo.textAlign, gTypo.font, gTypo.letterSpacing);
9166
+ const gTextX = computeTextX(gTypo, g.x, g.w) + (g.labelDx ?? 0);
9167
+ const gTextY = g.y + gTypo.padding + 2 + (g.labelDy ?? 0);
9168
+ drawText(ctx, g.label, gTextX, gTextY, gTypo.fontSize, gTypo.fontWeight, gTypo.textColor, gTypo.textAlign, gTypo.font, gTypo.letterSpacing);
9130
9169
  }
9131
9170
  if (gs.opacity != null)
9132
9171
  ctx.globalAlpha = 1;
@@ -9164,8 +9203,8 @@ function renderToCanvas(sg, canvas, options = {}) {
9164
9203
  if (arrowAt === 'start' || arrowAt === 'both')
9165
9204
  drawArrowHead(rc, x1, y1, Math.atan2(y1 - y2, x1 - x2), ecol, hashStr$3(e.from + 'back'));
9166
9205
  if (e.label) {
9167
- const mx = (x1 + x2) / 2 - ny * EDGE.labelOffset;
9168
- const my = (y1 + y2) / 2 + nx * EDGE.labelOffset;
9206
+ const mx = (x1 + x2) / 2 - ny * EDGE.labelOffset + (e.labelDx ?? 0);
9207
+ const my = (y1 + y2) / 2 + nx * EDGE.labelOffset + (e.labelDy ?? 0);
9169
9208
  // ── Edge label: font, font-size, letter-spacing ──
9170
9209
  // always center-anchored (single line)
9171
9210
  const eFontSize = Number(e.style?.fontSize ?? EDGE.labelFontSize);
@@ -9205,7 +9244,7 @@ function renderToCanvas(sg, canvas, options = {}) {
9205
9244
  // ── Node / text typography ─────────────────────────
9206
9245
  const isText = n.shape === 'text';
9207
9246
  const isNote = n.shape === 'note';
9208
- const isMediaShape = n.shape === 'icon' || n.shape === 'image' || n.shape === 'line';
9247
+ const usesBottomStrip = usesBottomLabelStrip(n.shape);
9209
9248
  const typo = resolveTypography(n.style, {
9210
9249
  fontSize: isText ? 13 : isNote ? 12 : 14,
9211
9250
  fontWeight: isText || isNote ? 400 : 500,
@@ -9223,23 +9262,25 @@ function renderToCanvas(sg, canvas, options = {}) {
9223
9262
  : n.x + typo.padding)
9224
9263
  : computeTextX(typo, n.x, n.w);
9225
9264
  const fontStr = buildFontStr(typo.fontSize, typo.fontWeight, typo.font);
9226
- const shouldWrap = !isMediaShape && !n.label.includes('\n');
9265
+ const shouldWrap = !usesBottomStrip && !n.label.includes('\n');
9227
9266
  const innerW = shapeInnerTextWidth(n.shape, n.w, typo.padding);
9228
9267
  const rawLines = n.label.split('\n');
9229
9268
  const lines = shouldWrap && rawLines.length === 1
9230
9269
  ? wrapText(n.label, innerW, typo.fontSize, fontStr)
9231
9270
  : rawLines;
9232
- const textCY = isMediaShape
9233
- ? n.y + n.h - 10
9271
+ const textCY = usesBottomStrip
9272
+ ? getBottomLabelCenterY(n)
9234
9273
  : isNote
9235
9274
  ? computeTextCY(typo, n.y, n.h, lines.length, FOLD + typo.padding)
9236
9275
  : computeTextCY(typo, n.y, n.h, lines.length);
9276
+ const labelX = textX + (n.labelDx ?? 0);
9277
+ const labelY = textCY + (n.labelDy ?? 0);
9237
9278
  if (n.label) {
9238
9279
  if (lines.length > 1) {
9239
- drawMultilineText(ctx, lines, textX, textCY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAlign, typo.lineHeight, typo.font, typo.letterSpacing);
9280
+ drawMultilineText(ctx, lines, labelX, labelY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAlign, typo.lineHeight, typo.font, typo.letterSpacing);
9240
9281
  }
9241
9282
  else {
9242
- drawText(ctx, lines[0] ?? '', textX, textCY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAlign, typo.font, typo.letterSpacing);
9283
+ drawText(ctx, lines[0] ?? '', labelX, labelY, typo.fontSize, typo.fontWeight, typo.textColor, typo.textAlign, typo.font, typo.letterSpacing);
9243
9284
  }
9244
9285
  }
9245
9286
  if (hasTx)
@@ -9577,7 +9618,7 @@ function buildNodeGuidePath(el) {
9577
9618
  [x + 1, y + h - 1],
9578
9619
  ]);
9579
9620
  case "line": {
9580
- const labelH = el.querySelector("text") ? 20 : 0;
9621
+ const labelH = el.querySelector("text") ? NODE.mediaLabelH : 0;
9581
9622
  const lineY = y + (h - labelH) / 2;
9582
9623
  return `M ${x} ${lineY} L ${x + w} ${lineY}`;
9583
9624
  }
@@ -12667,7 +12708,6 @@ const EMBED_CSS = `
12667
12708
  top: 0;
12668
12709
  left: 0;
12669
12710
  transform-origin: 0 0;
12670
- will-change: transform;
12671
12711
  }
12672
12712
 
12673
12713
  .skm-embed__error {