@retikz/core 0.1.0-alpha.2 → 0.1.0-alpha.4

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.
Files changed (119) hide show
  1. package/dist/es/compile/compile.d.ts +6 -0
  2. package/dist/es/compile/compile.d.ts.map +1 -1
  3. package/dist/es/compile/compile.js +33 -4
  4. package/dist/es/compile/node.d.ts +23 -2
  5. package/dist/es/compile/node.d.ts.map +1 -1
  6. package/dist/es/compile/node.js +94 -4
  7. package/dist/es/compile/path.d.ts +3 -2
  8. package/dist/es/compile/path.d.ts.map +1 -1
  9. package/dist/es/compile/path.js +333 -14
  10. package/dist/es/compile/position.d.ts +8 -5
  11. package/dist/es/compile/position.d.ts.map +1 -1
  12. package/dist/es/compile/position.js +32 -5
  13. package/dist/es/geometry/arc.d.ts +34 -0
  14. package/dist/es/geometry/arc.d.ts.map +1 -0
  15. package/dist/es/geometry/arc.js +53 -0
  16. package/dist/es/geometry/bend.d.ts +18 -0
  17. package/dist/es/geometry/bend.d.ts.map +1 -0
  18. package/dist/es/geometry/bend.js +29 -0
  19. package/dist/es/geometry/index.d.ts +3 -0
  20. package/dist/es/geometry/index.d.ts.map +1 -1
  21. package/dist/es/geometry/segment.d.ts +38 -0
  22. package/dist/es/geometry/segment.d.ts.map +1 -0
  23. package/dist/es/geometry/segment.js +82 -0
  24. package/dist/es/index.d.ts +4 -4
  25. package/dist/es/index.d.ts.map +1 -1
  26. package/dist/es/index.js +7 -4
  27. package/dist/es/ir/coordinate.d.ts +57 -0
  28. package/dist/es/ir/coordinate.d.ts.map +1 -0
  29. package/dist/es/ir/coordinate.js +27 -0
  30. package/dist/es/ir/index.d.ts +1 -0
  31. package/dist/es/ir/index.d.ts.map +1 -1
  32. package/dist/es/ir/node.d.ts +276 -17
  33. package/dist/es/ir/node.d.ts.map +1 -1
  34. package/dist/es/ir/node.js +28 -3
  35. package/dist/es/ir/path/path.d.ts +625 -15
  36. package/dist/es/ir/path/path.d.ts.map +1 -1
  37. package/dist/es/ir/path/path.js +22 -0
  38. package/dist/es/ir/path/step.d.ts +872 -20
  39. package/dist/es/ir/path/step.d.ts.map +1 -1
  40. package/dist/es/ir/path/step.js +86 -4
  41. package/dist/es/ir/path/target.d.ts +32 -2
  42. package/dist/es/ir/path/target.d.ts.map +1 -1
  43. package/dist/es/ir/path/target.js +7 -3
  44. package/dist/es/ir/position/at-position.d.ts +50 -0
  45. package/dist/es/ir/position/at-position.d.ts.map +1 -0
  46. package/dist/es/ir/position/at-position.js +30 -0
  47. package/dist/es/ir/position/index.d.ts +1 -0
  48. package/dist/es/ir/position/index.d.ts.map +1 -1
  49. package/dist/es/ir/scene.d.ts +2072 -112
  50. package/dist/es/ir/scene.d.ts.map +1 -1
  51. package/dist/es/ir/scene.js +6 -1
  52. package/dist/es/parsers/index.d.ts +1 -0
  53. package/dist/es/parsers/index.d.ts.map +1 -1
  54. package/dist/es/parsers/parseTargetSugar.d.ts +3 -0
  55. package/dist/es/parsers/parseTargetSugar.d.ts.map +1 -0
  56. package/dist/es/parsers/parseTargetSugar.js +31 -0
  57. package/dist/es/parsers/parseWay.d.ts +131 -22
  58. package/dist/es/parsers/parseWay.d.ts.map +1 -1
  59. package/dist/es/parsers/parseWay.js +149 -17
  60. package/dist/lib/compile/compile.cjs +33 -4
  61. package/dist/lib/compile/compile.d.ts +6 -0
  62. package/dist/lib/compile/compile.d.ts.map +1 -1
  63. package/dist/lib/compile/node.cjs +94 -4
  64. package/dist/lib/compile/node.d.ts +23 -2
  65. package/dist/lib/compile/node.d.ts.map +1 -1
  66. package/dist/lib/compile/path.cjs +333 -14
  67. package/dist/lib/compile/path.d.ts +3 -2
  68. package/dist/lib/compile/path.d.ts.map +1 -1
  69. package/dist/lib/compile/position.cjs +32 -5
  70. package/dist/lib/compile/position.d.ts +8 -5
  71. package/dist/lib/compile/position.d.ts.map +1 -1
  72. package/dist/lib/geometry/arc.cjs +55 -0
  73. package/dist/lib/geometry/arc.d.ts +34 -0
  74. package/dist/lib/geometry/arc.d.ts.map +1 -0
  75. package/dist/lib/geometry/bend.cjs +29 -0
  76. package/dist/lib/geometry/bend.d.ts +18 -0
  77. package/dist/lib/geometry/bend.d.ts.map +1 -0
  78. package/dist/lib/geometry/index.d.ts +3 -0
  79. package/dist/lib/geometry/index.d.ts.map +1 -1
  80. package/dist/lib/geometry/segment.cjs +88 -0
  81. package/dist/lib/geometry/segment.d.ts +38 -0
  82. package/dist/lib/geometry/segment.d.ts.map +1 -0
  83. package/dist/lib/index.cjs +18 -0
  84. package/dist/lib/index.d.ts +4 -4
  85. package/dist/lib/index.d.ts.map +1 -1
  86. package/dist/lib/ir/coordinate.cjs +27 -0
  87. package/dist/lib/ir/coordinate.d.ts +57 -0
  88. package/dist/lib/ir/coordinate.d.ts.map +1 -0
  89. package/dist/lib/ir/index.d.ts +1 -0
  90. package/dist/lib/ir/index.d.ts.map +1 -1
  91. package/dist/lib/ir/node.cjs +28 -2
  92. package/dist/lib/ir/node.d.ts +276 -17
  93. package/dist/lib/ir/node.d.ts.map +1 -1
  94. package/dist/lib/ir/path/path.cjs +22 -0
  95. package/dist/lib/ir/path/path.d.ts +625 -15
  96. package/dist/lib/ir/path/path.d.ts.map +1 -1
  97. package/dist/lib/ir/path/step.cjs +93 -3
  98. package/dist/lib/ir/path/step.d.ts +872 -20
  99. package/dist/lib/ir/path/step.d.ts.map +1 -1
  100. package/dist/lib/ir/path/target.cjs +8 -2
  101. package/dist/lib/ir/path/target.d.ts +32 -2
  102. package/dist/lib/ir/path/target.d.ts.map +1 -1
  103. package/dist/lib/ir/position/at-position.cjs +31 -0
  104. package/dist/lib/ir/position/at-position.d.ts +50 -0
  105. package/dist/lib/ir/position/at-position.d.ts.map +1 -0
  106. package/dist/lib/ir/position/index.d.ts +1 -0
  107. package/dist/lib/ir/position/index.d.ts.map +1 -1
  108. package/dist/lib/ir/scene.cjs +6 -1
  109. package/dist/lib/ir/scene.d.ts +2072 -112
  110. package/dist/lib/ir/scene.d.ts.map +1 -1
  111. package/dist/lib/parsers/index.d.ts +1 -0
  112. package/dist/lib/parsers/index.d.ts.map +1 -1
  113. package/dist/lib/parsers/parseTargetSugar.cjs +31 -0
  114. package/dist/lib/parsers/parseTargetSugar.d.ts +3 -0
  115. package/dist/lib/parsers/parseTargetSugar.d.ts.map +1 -0
  116. package/dist/lib/parsers/parseWay.cjs +149 -17
  117. package/dist/lib/parsers/parseWay.d.ts +131 -22
  118. package/dist/lib/parsers/parseWay.d.ts.map +1 -1
  119. package/package.json +1 -1
@@ -1,19 +1,46 @@
1
1
  //#region src/compile/position.ts
2
+ /** 默认相对定位距离(user units)——CompileOptions.nodeDistance 未提供时使用 */
3
+ var DEFAULT_NODE_DISTANCE = 1;
2
4
  /**
3
- * IR 里出现的位置形态(笛卡尔 / 极坐标 / 节点 id)解析为笛卡尔位置。
4
- * 极坐标的 origin 可递归 / 可引用节点 id;按节点定义顺序处理(前向引用要求节点先定义)。
5
- * 解析失败返回 null(如引用了未定义节点)。
5
+ * 8 方向到屏幕坐标系(y 向下)单位向量的映射。
6
+ * 视觉语义:above 在视觉上方(y 减小),below 在视觉下方(y 增大)。
7
+ * 4 对角分量为 1/√2,保证斜向距离与水平 / 垂直距离等长(对角点位于半径 = distance 的圆周上)。
6
8
  */
7
- var resolvePosition = (pos, nodeMap) => {
9
+ var DIRECTION_VECTOR = {
10
+ above: [0, -1],
11
+ below: [0, 1],
12
+ left: [-1, 0],
13
+ right: [1, 0],
14
+ "above-left": [-Math.SQRT1_2, -Math.SQRT1_2],
15
+ "above-right": [Math.SQRT1_2, -Math.SQRT1_2],
16
+ "below-left": [-Math.SQRT1_2, Math.SQRT1_2],
17
+ "below-right": [Math.SQRT1_2, Math.SQRT1_2]
18
+ };
19
+ /**
20
+ * 把 IR 里出现的位置形态(笛卡尔 / 极坐标 / 相对定位 / 节点 id)解析为笛卡尔位置。
21
+ * - 极坐标的 origin 可递归 / 可引用节点 id
22
+ * - 相对定位的 of 必须引用已定义的节点 / coordinate(前向引用要求被引节点先出现)
23
+ * - 解析失败返回 null(如引用了未定义节点)
24
+ *
25
+ * `nodeDistance` 是 Tikz 容器 prop 注入的相对定位默认距离;AtPosition 自带 distance 时优先用自带值。
26
+ */
27
+ var resolvePosition = (pos, nodeMap, nodeDistance = DEFAULT_NODE_DISTANCE) => {
8
28
  if (typeof pos === "string") {
9
29
  const node = nodeMap.get(pos);
10
30
  return node ? [node.rect.x, node.rect.y] : null;
11
31
  }
12
32
  if (Array.isArray(pos)) return pos;
33
+ if ("direction" in pos) {
34
+ const ref = nodeMap.get(pos.of);
35
+ if (!ref) return null;
36
+ const distance = pos.distance ?? nodeDistance;
37
+ const [dx, dy] = DIRECTION_VECTOR[pos.direction];
38
+ return [ref.rect.x + dx * distance, ref.rect.y + dy * distance];
39
+ }
13
40
  let origin;
14
41
  if (!pos.origin) origin = [0, 0];
15
42
  else {
16
- const resolved = resolvePosition(pos.origin, nodeMap);
43
+ const resolved = resolvePosition(pos.origin, nodeMap, nodeDistance);
17
44
  if (!resolved) return null;
18
45
  origin = resolved;
19
46
  }
@@ -1,9 +1,12 @@
1
- import { IRPosition, PolarPosition } from '../ir';
1
+ import { IRAtPosition, IRPosition, PolarPosition } from '../ir';
2
2
  import { NodeLayout } from './node';
3
3
  /**
4
- * 把 IR 里出现的位置形态(笛卡尔 / 极坐标 / 节点 id)解析为笛卡尔位置。
5
- * 极坐标的 origin 可递归 / 可引用节点 id;按节点定义顺序处理(前向引用要求节点先定义)。
6
- * 解析失败返回 null(如引用了未定义节点)。
4
+ * 把 IR 里出现的位置形态(笛卡尔 / 极坐标 / 相对定位 / 节点 id)解析为笛卡尔位置。
5
+ * - 极坐标的 origin 可递归 / 可引用节点 id
6
+ * - 相对定位的 of 必须引用已定义的节点 / coordinate(前向引用要求被引节点先出现)
7
+ * - 解析失败返回 null(如引用了未定义节点)
8
+ *
9
+ * `nodeDistance` 是 Tikz 容器 prop 注入的相对定位默认距离;AtPosition 自带 distance 时优先用自带值。
7
10
  */
8
- export declare const resolvePosition: (pos: IRPosition | PolarPosition | string, nodeMap: Map<string, NodeLayout>) => IRPosition | null;
11
+ export declare const resolvePosition: (pos: IRPosition | PolarPosition | IRAtPosition | string, nodeMap: Map<string, NodeLayout>, nodeDistance?: number) => IRPosition | null;
9
12
  //# sourceMappingURL=position.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../src/compile/position.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEzC;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,UAAU,GAAG,aAAa,GAAG,MAAM,EACxC,SAAS,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,KAC/B,UAAU,GAAG,IAoBf,CAAC"}
1
+ {"version":3,"file":"position.d.ts","sourceRoot":"","sources":["../../../src/compile/position.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAqBzC;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,KAAK,UAAU,GAAG,aAAa,GAAG,YAAY,GAAG,MAAM,EACvD,SAAS,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAChC,eAAc,MAA8B,KAC3C,UAAU,GAAG,IA4Bf,CAAC"}
@@ -0,0 +1,55 @@
1
+ //#region src/geometry/arc.ts
2
+ var DEG_TO_RAD = Math.PI / 180;
3
+ /**
4
+ * 给定圆心、半径、角度(度,与 polar.toPosition 同约定),返回圆周上对应点。
5
+ */
6
+ var arcEndPoint = (center, radius, angleDeg) => {
7
+ const rad = angleDeg * DEG_TO_RAD;
8
+ return [center[0] + Math.cos(rad) * radius, center[1] + Math.sin(rad) * radius];
9
+ };
10
+ /**
11
+ * 计算 SVG `<path>` A 命令需要的 large-arc-flag 与 sweep-flag。
12
+ *
13
+ * - `largeArc`:弧跨度 `|endAngle - startAngle|` 严格大于 180° 时为 1。
14
+ * - `sweep`:`endAngle >= startAngle` 时为 1,否则为 0;与"角度增加方向 = 在
15
+ * SVG 屏幕上视觉顺时针"一致——因为我们投影时未翻转 y,SVG sweep=1(屏幕 CW)
16
+ * 恰好等价 math 角度增加。
17
+ *
18
+ * 边界:`|Δ|=180°` 时 `largeArc=0`(半弧不算大弧);恰好同点 `|Δ|=0` 也返回 0。
19
+ */
20
+ var arcSvgFlags = (startAngleDeg, endAngleDeg) => {
21
+ return {
22
+ largeArc: Math.abs(endAngleDeg - startAngleDeg) > 180 ? 1 : 0,
23
+ sweep: endAngleDeg >= startAngleDeg ? 1 : 0
24
+ };
25
+ };
26
+ /**
27
+ * 弧的 bounding box 极值候选点:起点、终点,以及 `[startAngle, endAngle]` 区间
28
+ * 里所有 90°·k 的基本方向(0°、90°、180°、270° 及其周期延拓)对应的圆周点。
29
+ *
30
+ * 这些点是计算视图框(viewBox)/ bbox 时必须考虑的候选——因为弧线投影到 x/y
31
+ * 轴的极值只可能在弧端点或圆周上的轴向四点处出现。
32
+ *
33
+ * 说明:
34
+ * - 接受 `endAngle < startAngle`(CW math 方向):以 `min..max` 区间扫描 90°·k;
35
+ * 语义上是"无论扫描方向,此弧覆盖到的角度区间内的基本方向都算极值候选"。
36
+ * - 跨 360°(如 270° → 450°)也按数值区间处理,正确收录中间穿越的 0°、90° 等。
37
+ * - 不去重:若起点恰好落在 90°·k 上会同时出现两次,调用方根据需要再处理。
38
+ */
39
+ var arcBoundingPoints = (center, radius, startAngleDeg, endAngleDeg) => {
40
+ const points = [arcEndPoint(center, radius, startAngleDeg), arcEndPoint(center, radius, endAngleDeg)];
41
+ const lo = Math.min(startAngleDeg, endAngleDeg);
42
+ const hi = Math.max(startAngleDeg, endAngleDeg);
43
+ const kStart = Math.ceil(lo / 90);
44
+ const kEnd = Math.floor(hi / 90);
45
+ for (let k = kStart; k <= kEnd; k++) {
46
+ const angle = k * 90;
47
+ if (angle === startAngleDeg || angle === endAngleDeg) continue;
48
+ points.push(arcEndPoint(center, radius, angle));
49
+ }
50
+ return points;
51
+ };
52
+ //#endregion
53
+ exports.arcBoundingPoints = arcBoundingPoints;
54
+ exports.arcEndPoint = arcEndPoint;
55
+ exports.arcSvgFlags = arcSvgFlags;
@@ -0,0 +1,34 @@
1
+ import { Position } from './point';
2
+ /**
3
+ * 给定圆心、半径、角度(度,与 polar.toPosition 同约定),返回圆周上对应点。
4
+ */
5
+ export declare const arcEndPoint: (center: Position, radius: number, angleDeg: number) => Position;
6
+ /**
7
+ * 计算 SVG `<path>` A 命令需要的 large-arc-flag 与 sweep-flag。
8
+ *
9
+ * - `largeArc`:弧跨度 `|endAngle - startAngle|` 严格大于 180° 时为 1。
10
+ * - `sweep`:`endAngle >= startAngle` 时为 1,否则为 0;与"角度增加方向 = 在
11
+ * SVG 屏幕上视觉顺时针"一致——因为我们投影时未翻转 y,SVG sweep=1(屏幕 CW)
12
+ * 恰好等价 math 角度增加。
13
+ *
14
+ * 边界:`|Δ|=180°` 时 `largeArc=0`(半弧不算大弧);恰好同点 `|Δ|=0` 也返回 0。
15
+ */
16
+ export declare const arcSvgFlags: (startAngleDeg: number, endAngleDeg: number) => {
17
+ largeArc: 0 | 1;
18
+ sweep: 0 | 1;
19
+ };
20
+ /**
21
+ * 弧的 bounding box 极值候选点:起点、终点,以及 `[startAngle, endAngle]` 区间
22
+ * 里所有 90°·k 的基本方向(0°、90°、180°、270° 及其周期延拓)对应的圆周点。
23
+ *
24
+ * 这些点是计算视图框(viewBox)/ bbox 时必须考虑的候选——因为弧线投影到 x/y
25
+ * 轴的极值只可能在弧端点或圆周上的轴向四点处出现。
26
+ *
27
+ * 说明:
28
+ * - 接受 `endAngle < startAngle`(CW math 方向):以 `min..max` 区间扫描 90°·k;
29
+ * 语义上是"无论扫描方向,此弧覆盖到的角度区间内的基本方向都算极值候选"。
30
+ * - 跨 360°(如 270° → 450°)也按数值区间处理,正确收录中间穿越的 0°、90° 等。
31
+ * - 不去重:若起点恰好落在 90°·k 上会同时出现两次,调用方根据需要再处理。
32
+ */
33
+ export declare const arcBoundingPoints: (center: Position, radius: number, startAngleDeg: number, endAngleDeg: number) => Array<Position>;
34
+ //# sourceMappingURL=arc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arc.d.ts","sourceRoot":"","sources":["../../../src/geometry/arc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkBxC;;GAEG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,QAAQ,EAChB,QAAQ,MAAM,EACd,UAAU,MAAM,KACf,QAMF,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GACtB,eAAe,MAAM,EACrB,aAAa,MAAM,KAClB;IAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAA;CAMjC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,QAAQ,EAChB,QAAQ,MAAM,EACd,eAAe,MAAM,EACrB,aAAa,MAAM,KAClB,KAAK,CAAC,QAAQ,CAmBhB,CAAC"}
@@ -0,0 +1,29 @@
1
+ //#region src/geometry/bend.ts
2
+ /**
3
+ * 用 cubic Bezier 拟合 from→to 的弧形 bend。
4
+ *
5
+ * 算法(ADR-0001):
6
+ * 1. apex offset = chord × tan(bendAngle / 2)(沿 path 法向 left / right 偏移量)
7
+ * 2. 控制点取 chord 1/3 / 2/3 处沿法向偏移;为让 cubic 在 t=0.5 处穿过 apex,
8
+ * 控制点 offset = (4/3) × apex offset(推导:B(0.5) = midpoint + (3/4)·s·n)
9
+ *
10
+ * 法向定义(SVG y 向下,"left/right" 按视觉,不按数学):
11
+ * chord direction = (dx, dy) / |chord|
12
+ * visual-left normal = ( dy, -dx) / |chord| (从 from 看向 to,向左偏)
13
+ * visual-right normal = (-dy, dx) / |chord|
14
+ *
15
+ * chord 长度为 0 时无方向可推,两个控制点都返回 from。
16
+ */
17
+ var bendControlPoints = (from, to, direction, bendAngle) => {
18
+ const dx = to[0] - from[0];
19
+ const dy = to[1] - from[1];
20
+ const chord = Math.hypot(dx, dy);
21
+ if (chord === 0) return [[from[0], from[1]], [from[0], from[1]]];
22
+ const sign = direction === "left" ? 1 : -1;
23
+ const nx = dy / chord * sign;
24
+ const ny = -dx / chord * sign;
25
+ const ctlOffset = 4 / 3 * (chord * Math.tan(bendAngle * Math.PI / 180 / 2));
26
+ return [[from[0] + dx / 3 + ctlOffset * nx, from[1] + dy / 3 + ctlOffset * ny], [from[0] + 2 * dx / 3 + ctlOffset * nx, from[1] + 2 * dy / 3 + ctlOffset * ny]];
27
+ };
28
+ //#endregion
29
+ exports.bendControlPoints = bendControlPoints;
@@ -0,0 +1,18 @@
1
+ import { Position } from './point';
2
+ /**
3
+ * 用 cubic Bezier 拟合 from→to 的弧形 bend。
4
+ *
5
+ * 算法(ADR-0001):
6
+ * 1. apex offset = chord × tan(bendAngle / 2)(沿 path 法向 left / right 偏移量)
7
+ * 2. 控制点取 chord 1/3 / 2/3 处沿法向偏移;为让 cubic 在 t=0.5 处穿过 apex,
8
+ * 控制点 offset = (4/3) × apex offset(推导:B(0.5) = midpoint + (3/4)·s·n)
9
+ *
10
+ * 法向定义(SVG y 向下,"left/right" 按视觉,不按数学):
11
+ * chord direction = (dx, dy) / |chord|
12
+ * visual-left normal = ( dy, -dx) / |chord| (从 from 看向 to,向左偏)
13
+ * visual-right normal = (-dy, dx) / |chord|
14
+ *
15
+ * chord 长度为 0 时无方向可推,两个控制点都返回 from。
16
+ */
17
+ export declare const bendControlPoints: (from: Position, to: Position, direction: "left" | "right", bendAngle: number) => [Position, Position];
18
+ //# sourceMappingURL=bend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bend.d.ts","sourceRoot":"","sources":["../../../src/geometry/bend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,QAAQ,EACd,IAAI,QAAQ,EACZ,WAAW,MAAM,GAAG,OAAO,EAC3B,WAAW,MAAM,KAChB,CAAC,QAAQ,EAAE,QAAQ,CAgBrB,CAAC"}
@@ -4,4 +4,7 @@ export * from './circle';
4
4
  export * from './ellipse';
5
5
  export * from './diamond';
6
6
  export * from './polar';
7
+ export * from './bend';
8
+ export * from './arc';
9
+ export * from './segment';
7
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/geometry/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/geometry/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC"}
@@ -0,0 +1,88 @@
1
+ //#region src/geometry/segment.ts
2
+ var DEG_TO_RAD = Math.PI / 180;
3
+ var normalize = (v) => {
4
+ const len = Math.hypot(v[0], v[1]);
5
+ if (len === 0) return [1, 0];
6
+ return [v[0] / len, v[1] / len];
7
+ };
8
+ /** 直线段 from → to */
9
+ var lineSegmentSample = (from, to, t) => ({
10
+ point: [from[0] + (to[0] - from[0]) * t, from[1] + (to[1] - from[1]) * t],
11
+ tangent: normalize([to[0] - from[0], to[1] - from[1]])
12
+ });
13
+ /**
14
+ * 二次贝塞尔 from → control → to。
15
+ * P(t) = (1-t)²·P0 + 2(1-t)t·P1 + t²·P2
16
+ * P'(t) = 2(1-t)(P1-P0) + 2t(P2-P1)
17
+ */
18
+ var quadSegmentSample = (from, control, to, t) => {
19
+ const u = 1 - t;
20
+ return {
21
+ point: [u * u * from[0] + 2 * u * t * control[0] + t * t * to[0], u * u * from[1] + 2 * u * t * control[1] + t * t * to[1]],
22
+ tangent: normalize([2 * u * (control[0] - from[0]) + 2 * t * (to[0] - control[0]), 2 * u * (control[1] - from[1]) + 2 * t * (to[1] - control[1])])
23
+ };
24
+ };
25
+ /**
26
+ * 三次贝塞尔 from → c1 → c2 → to。
27
+ * P'(t) = 3(1-t)²(P1-P0) + 6(1-t)t(P2-P1) + 3t²(P3-P2)
28
+ */
29
+ var cubicSegmentSample = (from, c1, c2, to, t) => {
30
+ const u = 1 - t;
31
+ return {
32
+ point: [u * u * u * from[0] + 3 * u * u * t * c1[0] + 3 * u * t * t * c2[0] + t * t * t * to[0], u * u * u * from[1] + 3 * u * u * t * c1[1] + 3 * u * t * t * c2[1] + t * t * t * to[1]],
33
+ tangent: normalize([3 * u * u * (c1[0] - from[0]) + 6 * u * t * (c2[0] - c1[0]) + 3 * t * t * (to[0] - c2[0]), 3 * u * u * (c1[1] - from[1]) + 6 * u * t * (c2[1] - c1[1]) + 3 * t * t * (to[1] - c2[1])])
34
+ };
35
+ };
36
+ /**
37
+ * 折角段 from → corner → to。
38
+ * t∈[0, 0.5] 走第一段(参数 2t);t∈(0.5, 1] 走第二段(参数 2t-1)。
39
+ * t=0.5 落在 corner,切线取第一段方向(与"靠近 prev 一侧"一致)。
40
+ */
41
+ var foldSegmentSample = (from, corner, to, t) => {
42
+ if (t <= .5) return lineSegmentSample(from, corner, t * 2);
43
+ return lineSegmentSample(corner, to, t * 2 - 1);
44
+ };
45
+ /**
46
+ * 弧段(与 ir/path arc 同约定,角度单位为度)。
47
+ * 切线沿"扫描方向"——endAngle ≥ startAngle 时为 (-sin, cos),否则反向。
48
+ */
49
+ var arcSegmentSample = (center, radius, startAngleDeg, endAngleDeg, t) => {
50
+ const rad = (startAngleDeg + t * (endAngleDeg - startAngleDeg)) * DEG_TO_RAD;
51
+ const cos = Math.cos(rad);
52
+ const sin = Math.sin(rad);
53
+ const sweepSign = endAngleDeg >= startAngleDeg ? 1 : -1;
54
+ return {
55
+ point: [center[0] + radius * cos, center[1] + radius * sin],
56
+ tangent: normalize([-sin * sweepSign, cos * sweepSign])
57
+ };
58
+ };
59
+ /**
60
+ * 整圆——从 0°(east)开始,与 compile/path circlePath 输出方向(右→左→右,sweep=1)一致。
61
+ */
62
+ var circleSegmentSample = (center, radius, t) => {
63
+ const rad = t * 360 * DEG_TO_RAD;
64
+ const cos = Math.cos(rad);
65
+ const sin = Math.sin(rad);
66
+ return {
67
+ point: [center[0] + radius * cos, center[1] + radius * sin],
68
+ tangent: normalize([-sin, cos])
69
+ };
70
+ };
71
+ /** 整椭圆——参数化 (rx·cos(2πt), ry·sin(2πt)) */
72
+ var ellipseSegmentSample = (center, rx, ry, t) => {
73
+ const rad = t * 360 * DEG_TO_RAD;
74
+ const cos = Math.cos(rad);
75
+ const sin = Math.sin(rad);
76
+ return {
77
+ point: [center[0] + rx * cos, center[1] + ry * sin],
78
+ tangent: normalize([-rx * sin, ry * cos])
79
+ };
80
+ };
81
+ //#endregion
82
+ exports.arcSegmentSample = arcSegmentSample;
83
+ exports.circleSegmentSample = circleSegmentSample;
84
+ exports.cubicSegmentSample = cubicSegmentSample;
85
+ exports.ellipseSegmentSample = ellipseSegmentSample;
86
+ exports.foldSegmentSample = foldSegmentSample;
87
+ exports.lineSegmentSample = lineSegmentSample;
88
+ exports.quadSegmentSample = quadSegmentSample;
@@ -0,0 +1,38 @@
1
+ import { Position } from './point';
2
+ export type SegmentSample = {
3
+ /** t 处的点坐标 */
4
+ point: Position;
5
+ /** t 处的切线方向(单位向量;零向量时回退到 [1, 0]) */
6
+ tangent: Position;
7
+ };
8
+ /** 直线段 from → to */
9
+ export declare const lineSegmentSample: (from: Position, to: Position, t: number) => SegmentSample;
10
+ /**
11
+ * 二次贝塞尔 from → control → to。
12
+ * P(t) = (1-t)²·P0 + 2(1-t)t·P1 + t²·P2
13
+ * P'(t) = 2(1-t)(P1-P0) + 2t(P2-P1)
14
+ */
15
+ export declare const quadSegmentSample: (from: Position, control: Position, to: Position, t: number) => SegmentSample;
16
+ /**
17
+ * 三次贝塞尔 from → c1 → c2 → to。
18
+ * P'(t) = 3(1-t)²(P1-P0) + 6(1-t)t(P2-P1) + 3t²(P3-P2)
19
+ */
20
+ export declare const cubicSegmentSample: (from: Position, c1: Position, c2: Position, to: Position, t: number) => SegmentSample;
21
+ /**
22
+ * 折角段 from → corner → to。
23
+ * t∈[0, 0.5] 走第一段(参数 2t);t∈(0.5, 1] 走第二段(参数 2t-1)。
24
+ * t=0.5 落在 corner,切线取第一段方向(与"靠近 prev 一侧"一致)。
25
+ */
26
+ export declare const foldSegmentSample: (from: Position, corner: Position, to: Position, t: number) => SegmentSample;
27
+ /**
28
+ * 弧段(与 ir/path arc 同约定,角度单位为度)。
29
+ * 切线沿"扫描方向"——endAngle ≥ startAngle 时为 (-sin, cos),否则反向。
30
+ */
31
+ export declare const arcSegmentSample: (center: Position, radius: number, startAngleDeg: number, endAngleDeg: number, t: number) => SegmentSample;
32
+ /**
33
+ * 整圆——从 0°(east)开始,与 compile/path circlePath 输出方向(右→左→右,sweep=1)一致。
34
+ */
35
+ export declare const circleSegmentSample: (center: Position, radius: number, t: number) => SegmentSample;
36
+ /** 整椭圆——参数化 (rx·cos(2πt), ry·sin(2πt)) */
37
+ export declare const ellipseSegmentSample: (center: Position, rx: number, ry: number, t: number) => SegmentSample;
38
+ //# sourceMappingURL=segment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segment.d.ts","sourceRoot":"","sources":["../../../src/geometry/segment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAuBxC,MAAM,MAAM,aAAa,GAAG;IAC1B,cAAc;IACd,KAAK,EAAE,QAAQ,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,QAAQ,CAAC;CACnB,CAAC;AAQF,oBAAoB;AACpB,eAAO,MAAM,iBAAiB,GAC5B,MAAM,QAAQ,EACd,IAAI,QAAQ,EACZ,GAAG,MAAM,KACR,aAGD,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,QAAQ,EACd,SAAS,QAAQ,EACjB,IAAI,QAAQ,EACZ,GAAG,MAAM,KACR,aASF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAC7B,MAAM,QAAQ,EACd,IAAI,QAAQ,EACZ,IAAI,QAAQ,EACZ,IAAI,QAAQ,EACZ,GAAG,MAAM,KACR,aAqBF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,QAAQ,EACd,QAAQ,QAAQ,EAChB,IAAI,QAAQ,EACZ,GAAG,MAAM,KACR,aAGF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,GAC3B,QAAQ,QAAQ,EAChB,QAAQ,MAAM,EACd,eAAe,MAAM,EACrB,aAAa,MAAM,EACnB,GAAG,MAAM,KACR,aAUF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,GAC9B,QAAQ,QAAQ,EAChB,QAAQ,MAAM,EACd,GAAG,MAAM,KACR,aASF,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,oBAAoB,GAC/B,QAAQ,QAAQ,EAChB,IAAI,MAAM,EACV,IAAI,MAAM,EACV,GAAG,MAAM,KACR,aASF,CAAC"}
@@ -1,11 +1,13 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_position = require("./ir/position/position.cjs");
3
3
  const require_polar_position = require("./ir/position/polar-position.cjs");
4
+ const require_at_position = require("./ir/position/at-position.cjs");
4
5
  const require_arrow = require("./ir/path/arrow.cjs");
5
6
  const require_target = require("./ir/path/target.cjs");
6
7
  const require_step = require("./ir/path/step.cjs");
7
8
  const require_path = require("./ir/path/path.cjs");
8
9
  const require_node = require("./ir/node.cjs");
10
+ const require_coordinate = require("./ir/coordinate.cjs");
9
11
  const require_scene = require("./ir/scene.cjs");
10
12
  const require_rect = require("./geometry/rect.cjs");
11
13
  const require_circle = require("./geometry/circle.cjs");
@@ -13,14 +15,25 @@ const require_diamond = require("./geometry/diamond.cjs");
13
15
  const require_ellipse = require("./geometry/ellipse.cjs");
14
16
  const require_text_metrics = require("./compile/text-metrics.cjs");
15
17
  const require_compile = require("./compile/compile.cjs");
18
+ const require_parseTargetSugar = require("./parsers/parseTargetSugar.cjs");
16
19
  const require_parseWay = require("./parsers/parseWay.cjs");
17
20
  const require_polar = require("./geometry/polar.cjs");
18
21
  const require_point = require("./geometry/point.cjs");
19
22
  exports.ARROW_SHAPES = require_arrow.ARROW_SHAPES;
23
+ exports.AT_DIRECTIONS = require_at_position.AT_DIRECTIONS;
24
+ exports.ArcStepSchema = require_step.ArcStepSchema;
25
+ exports.AtPositionSchema = require_at_position.AtPositionSchema;
26
+ exports.BendStepSchema = require_step.BendStepSchema;
20
27
  exports.CURRENT_IR_VERSION = require_scene.CURRENT_IR_VERSION;
21
28
  exports.ChildSchema = require_scene.ChildSchema;
29
+ exports.CirclePathStepSchema = require_step.CirclePathStepSchema;
30
+ exports.ControlPointSchema = require_step.ControlPointSchema;
31
+ exports.CoordinateSchema = require_coordinate.CoordinateSchema;
32
+ exports.CubicStepSchema = require_step.CubicStepSchema;
33
+ exports.CurveStepSchema = require_step.CurveStepSchema;
22
34
  exports.CycleStepSchema = require_step.CycleStepSchema;
23
35
  exports.DrawWay = require_parseWay.DrawWay;
36
+ exports.EllipsePathStepSchema = require_step.EllipsePathStepSchema;
24
37
  exports.FoldStepSchema = require_step.FoldStepSchema;
25
38
  exports.FontSchema = require_node.FontSchema;
26
39
  exports.LineSpecSchema = require_node.LineSpecSchema;
@@ -28,13 +41,17 @@ exports.LineStepSchema = require_step.LineStepSchema;
28
41
  exports.MoveStepSchema = require_step.MoveStepSchema;
29
42
  exports.NODE_SHAPES = require_node.NODE_SHAPES;
30
43
  exports.NODE_TEXT_ALIGNS = require_node.NODE_TEXT_ALIGNS;
44
+ exports.NodeLabelSchema = require_node.NodeLabelSchema;
31
45
  exports.NodeSchema = require_node.NodeSchema;
32
46
  exports.NodeTextSchema = require_node.NodeTextSchema;
33
47
  exports.PathSchema = require_path.PathSchema;
34
48
  exports.PolarPositionSchema = require_polar_position.PolarPositionSchema;
35
49
  exports.PositionSchema = require_position.PositionSchema;
36
50
  exports.RECT_ANCHORS = require_rect.RECT_ANCHORS;
51
+ exports.RelAccumulateTargetSchema = require_target.RelAccumulateTargetSchema;
52
+ exports.RelTargetSchema = require_target.RelTargetSchema;
37
53
  exports.SceneSchema = require_scene.SceneSchema;
54
+ exports.StepLabelSchema = require_step.StepLabelSchema;
38
55
  exports.StepSchema = require_step.StepSchema;
39
56
  exports.TargetSchema = require_target.TargetSchema;
40
57
  exports.circle = require_circle.circle;
@@ -42,6 +59,7 @@ exports.compileToScene = require_compile.compileToScene;
42
59
  exports.diamond = require_diamond.diamond;
43
60
  exports.ellipse = require_ellipse.ellipse;
44
61
  exports.fallbackMeasurer = require_text_metrics.fallbackMeasurer;
62
+ exports.parseTargetSugar = require_parseTargetSugar.parseTargetSugar;
45
63
  exports.parseWay = require_parseWay.parseWay;
46
64
  exports.point = require_point.point;
47
65
  exports.polar = require_polar.polar;
@@ -6,14 +6,14 @@
6
6
  *
7
7
  * 本包零 React、零 DOM 依赖。
8
8
  */
9
- export { PositionSchema, PolarPositionSchema, TargetSchema, MoveStepSchema, LineStepSchema, FoldStepSchema, CycleStepSchema, StepSchema, NodeSchema, FontSchema, NodeTextSchema, LineSpecSchema, PathSchema, ChildSchema, SceneSchema, CURRENT_IR_VERSION, } from './ir';
10
- export type { IRPosition, IRTarget, IRMoveStep, IRLineStep, IRFoldStep, IRCycleStep, IRStep, IRNode, IRFont, IRLineSpec, IRPath, IRChild, IR, ArrowShape, NodeShape, NodeTextAlign, } from './ir';
9
+ export { PositionSchema, PolarPositionSchema, AtPositionSchema, AT_DIRECTIONS, TargetSchema, RelTargetSchema, RelAccumulateTargetSchema, MoveStepSchema, LineStepSchema, FoldStepSchema, CycleStepSchema, CurveStepSchema, CubicStepSchema, BendStepSchema, ArcStepSchema, CirclePathStepSchema, EllipsePathStepSchema, ControlPointSchema, StepLabelSchema, StepSchema, NodeSchema, NodeLabelSchema, CoordinateSchema, FontSchema, NodeTextSchema, LineSpecSchema, PathSchema, ChildSchema, SceneSchema, CURRENT_IR_VERSION, } from './ir';
10
+ export type { IRPosition, IRAtPosition, AtDirection, IRTarget, IRRelTarget, IRRelAccumulateTarget, IRMoveStep, IRLineStep, IRFoldStep, IRCycleStep, IRCurveStep, IRCubicStep, IRBendStep, IRArcStep, IRCirclePathStep, IREllipsePathStep, IRControlPoint, IRStepLabel, IRStep, IRNode, IRNodeLabel, IRCoordinate, IRFont, IRLineSpec, IRPath, IRChild, IR, ArrowShape, NodeShape, NodeTextAlign, } from './ir';
11
11
  export { ARROW_SHAPES, NODE_SHAPES, NODE_TEXT_ALIGNS } from './ir';
12
12
  export type { ScenePrimitive, RectPrim, EllipsePrim, TextPrim, TextLine, PathPrim, GroupPrim, ViewBox, Scene, } from './primitive';
13
13
  export type { FontSpec, TextMetrics, TextMeasurer, CompileOptions, } from './compile';
14
14
  export { fallbackMeasurer, compileToScene } from './compile';
15
- export type { WayItem, WayDSL, WayCycle, WayVia } from './parsers';
16
- export { parseWay, DrawWay } from './parsers';
15
+ export type { WayItem, WayDSL, WayCycle, WayVia, WayRelItem, WayLabel, WayLabelOp, } from './parsers';
16
+ export { parseWay, DrawWay, parseTargetSugar } from './parsers';
17
17
  export type { Position, Rect, RectAnchor, Circle, CircleAnchor, Ellipse, EllipseAnchor, Diamond, DiamondAnchor, PolarPosition, } from './geometry';
18
18
  export { point, rect, circle, ellipse, diamond, RECT_ANCHORS, polar } from './geometry';
19
19
  export type { ValueOf } from './types';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,UAAU,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,MAAM,CAAC;AACd,YAAY,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,MAAM,EACN,MAAM,EACN,MAAM,EACN,UAAU,EACV,MAAM,EACN,OAAO,EACP,EAAE,EACF,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AAGnE,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,OAAO,EACP,KAAK,GACN,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG7D,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAI9C,YAAY,EACV,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,MAAM,EACN,YAAY,EACZ,OAAO,EACP,aAAa,EACb,OAAO,EACP,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxF,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,UAAU,EACV,UAAU,EACV,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,cAAc,EACd,cAAc,EACd,UAAU,EACV,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,MAAM,CAAC;AACd,YAAY,EACV,UAAU,EACV,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,WAAW,EACX,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,WAAW,EACX,MAAM,EACN,MAAM,EACN,WAAW,EACX,YAAY,EACZ,MAAM,EACN,UAAU,EACV,MAAM,EACN,OAAO,EACP,EAAE,EACF,UAAU,EACV,SAAS,EACT,aAAa,GACd,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,MAAM,CAAC;AAGnE,YAAY,EACV,cAAc,EACd,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,OAAO,EACP,KAAK,GACN,MAAM,aAAa,CAAC;AAGrB,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG7D,YAAY,EACV,OAAO,EACP,MAAM,EACN,QAAQ,EACR,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,GACX,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAIhE,YAAY,EACV,QAAQ,EACR,IAAI,EACJ,UAAU,EACV,MAAM,EACN,YAAY,EACZ,OAAO,EACP,aAAa,EACb,OAAO,EACP,aAAa,EACb,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxF,YAAY,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,27 @@
1
+ const require_position = require("./position/position.cjs");
2
+ const require_polar_position = require("./position/polar-position.cjs");
3
+ const require_at_position = require("./position/at-position.cjs");
4
+ let zod = require("zod");
5
+ //#region src/ir/coordinate.ts
6
+ /**
7
+ * Coordinate(占位节点)——TikZ `\coordinate (m) at (3,2);` 同义。
8
+ *
9
+ * 命名一个点供后续 path / at 引用,自身不绘制任何图形。
10
+ * 支持笛卡尔 / 极坐标 / 相对定位三种 position 形态,与 `Node.position` 完全一致。
11
+ *
12
+ * 特点:
13
+ * - 必须有 `id`(无 id 的占位节点没有意义)
14
+ * - 不参与 viewBox 扩展(无视觉边界);只在被引用时才间接影响 viewBox(通过引用它的 node / path)
15
+ * - 与 Node 在同一个 nodeIndex 中注册——path target 字符串、`Node.position.of` 都能命中 coordinate id
16
+ */
17
+ var CoordinateSchema = zod.z.object({
18
+ type: zod.z.literal("coordinate").describe("Discriminator marking this child as a coordinate placeholder"),
19
+ id: zod.z.string().min(1).describe("Required unique id; the whole point of a coordinate is to be referenced by paths or other nodes"),
20
+ position: zod.z.union([
21
+ require_position.PositionSchema,
22
+ require_polar_position.PolarPositionSchema,
23
+ require_at_position.AtPositionSchema
24
+ ]).describe("Coordinate position; Cartesian [x, y], polar, or relative-to-another-node (`at`-style). Resolved at compile time.")
25
+ }).describe("Coordinate placeholder: a named point with no visual; usable as a target for paths and as an anchor for relative positioning. Mirrors TikZ `\\coordinate (id) at (...);`");
26
+ //#endregion
27
+ exports.CoordinateSchema = CoordinateSchema;
@@ -0,0 +1,57 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Coordinate(占位节点)——TikZ `\coordinate (m) at (3,2);` 同义。
4
+ *
5
+ * 命名一个点供后续 path / at 引用,自身不绘制任何图形。
6
+ * 支持笛卡尔 / 极坐标 / 相对定位三种 position 形态,与 `Node.position` 完全一致。
7
+ *
8
+ * 特点:
9
+ * - 必须有 `id`(无 id 的占位节点没有意义)
10
+ * - 不参与 viewBox 扩展(无视觉边界);只在被引用时才间接影响 viewBox(通过引用它的 node / path)
11
+ * - 与 Node 在同一个 nodeIndex 中注册——path target 字符串、`Node.position.of` 都能命中 coordinate id
12
+ */
13
+ export declare const CoordinateSchema: z.ZodObject<{
14
+ type: z.ZodLiteral<"coordinate">;
15
+ id: z.ZodString;
16
+ position: z.ZodUnion<[z.ZodTuple<[z.ZodNumber, z.ZodNumber], null>, z.ZodType<import('./position').PolarPosition, z.ZodTypeDef, import('./position').PolarPosition>, z.ZodObject<{
17
+ direction: z.ZodNativeEnum<{
18
+ readonly above: "above";
19
+ readonly below: "below";
20
+ readonly left: "left";
21
+ readonly right: "right";
22
+ readonly 'above-left': "above-left";
23
+ readonly 'above-right': "above-right";
24
+ readonly 'below-left': "below-left";
25
+ readonly 'below-right': "below-right";
26
+ }>;
27
+ of: z.ZodString;
28
+ distance: z.ZodOptional<z.ZodNumber>;
29
+ }, "strip", z.ZodTypeAny, {
30
+ direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
31
+ of: string;
32
+ distance?: number | undefined;
33
+ }, {
34
+ direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
35
+ of: string;
36
+ distance?: number | undefined;
37
+ }>]>;
38
+ }, "strip", z.ZodTypeAny, {
39
+ type: "coordinate";
40
+ position: [number, number] | import('./position').PolarPosition | {
41
+ direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
42
+ of: string;
43
+ distance?: number | undefined;
44
+ };
45
+ id: string;
46
+ }, {
47
+ type: "coordinate";
48
+ position: [number, number] | import('./position').PolarPosition | {
49
+ direction: "above" | "below" | "left" | "right" | "above-left" | "above-right" | "below-left" | "below-right";
50
+ of: string;
51
+ distance?: number | undefined;
52
+ };
53
+ id: string;
54
+ }>;
55
+ /** Coordinate IR 类型——`{ type: 'coordinate', id, position }` */
56
+ export type IRCoordinate = z.infer<typeof CoordinateSchema>;
57
+ //# sourceMappingURL=coordinate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinate.d.ts","sourceRoot":"","sources":["../../../src/ir/coordinate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB1B,CAAC;AAEJ,+DAA+D;AAC/D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  export * from './position';
2
2
  export * from './path';
3
3
  export * from './node';
4
+ export * from './coordinate';
4
5
  export * from './scene';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ir/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ir/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
@@ -1,5 +1,6 @@
1
1
  const require_position = require("./position/position.cjs");
2
2
  const require_polar_position = require("./position/polar-position.cjs");
3
+ const require_at_position = require("./position/at-position.cjs");
3
4
  let zod = require("zod");
4
5
  //#region src/ir/node.ts
5
6
  /**
@@ -70,11 +71,34 @@ var NODE_TEXT_ALIGNS = {
70
71
  center: "center",
71
72
  right: "right"
72
73
  };
74
+ /**
75
+ * 节点附属标签(label)——TikZ `[label=above:foo]` / `[label={[red]30:foo}]` 同义。
76
+ *
77
+ * 一个 Node 可挂多个 label(数组形态);label 自身不参与 viewBox(视觉外延少时可接受)。
78
+ *
79
+ * `position` 接受两种形态:
80
+ * - 8 方向枚举(`above` / `right` / `above-left` ...):标签贴在 node 该方向边界外
81
+ * - 数字角度:以 node 中心为原点,按该角度方向投射;约定与 polar 一致(0° = +x,90° = +y 屏幕下方)
82
+ *
83
+ * 默认 `position = 'above'`,`distance = 4`(user units,标签与 node 边界的距离)。
84
+ */
85
+ var NodeLabelSchema = zod.z.object({
86
+ text: zod.z.string().describe("Label text content; rendered as a single line."),
87
+ position: zod.z.union([zod.z.nativeEnum(require_at_position.AT_DIRECTIONS), zod.z.number()]).optional().describe("Placement around the node border: 8-direction enum (above / right / above-left / ...) or numeric angle in degrees (`label=30:foo` for radial placement). Default `above`. Numeric uses the polar convention (0° = +x, 90° = +y, screen-down)."),
88
+ distance: zod.z.number().nonnegative().optional().describe("Gap between the node border and the label center, in user units. Default 4."),
89
+ textColor: zod.z.string().optional().describe("Label text color; falls back to currentColor."),
90
+ opacity: zod.z.number().min(0).max(1).optional().describe("Label-only opacity 0..1; multiplied with the node opacity if both are set."),
91
+ font: FontSchema.optional().describe("Label font overrides; missing fields inherit from the parent node font, then renderer defaults.")
92
+ }).describe("Extra text attached around a node border. Multiple labels supported via array form on `Node.label`.");
73
93
  var NodeSchema = zod.z.object({
74
94
  type: zod.z.literal("node").describe("Discriminator marking this child as a node"),
75
95
  id: zod.z.string().min(1).optional().describe("Optional unique id; required if any path needs to reference this node by string"),
76
96
  shape: zod.z.nativeEnum(NODE_SHAPES).optional().describe("Node visual shape; defaults to `rectangle`. The boundary fully contains text + padding (circumscribed for circle / ellipse / diamond)."),
77
- position: zod.z.union([require_position.PositionSchema, require_polar_position.PolarPositionSchema]).describe("Center point of the node content box; Cartesian [x, y] or polar (resolved at compile time)"),
97
+ position: zod.z.union([
98
+ require_position.PositionSchema,
99
+ require_polar_position.PolarPositionSchema,
100
+ require_at_position.AtPositionSchema
101
+ ]).describe("Center point of the node content box; Cartesian [x, y], polar, or relative-to-another-node (`at`-style with `direction` / `of` / `distance?`). All non-Cartesian forms resolve at compile time."),
78
102
  rotate: zod.z.number().optional().describe("Rotation in degrees around the node center; positive = clockwise (matches TikZ rotate=...)"),
79
103
  text: NodeTextSchema.optional(),
80
104
  align: zod.z.nativeEnum(NODE_TEXT_ALIGNS).optional().describe("Multi-line text alignment within the text block; `left` / `center` / `right`. Defaults to `center` (matches TikZ)."),
@@ -101,12 +125,14 @@ var NodeSchema = zod.z.object({
101
125
  outerSep: zod.z.number().nonnegative().optional().describe("Outer margin from border to path attachment point in user units; does NOT change the visible border. Falls back to `margin`."),
102
126
  padding: zod.z.number().nonnegative().optional().describe("Symmetric inner padding (alias for `innerXSep` + `innerYSep`); axis-specific fields take precedence."),
103
127
  margin: zod.z.number().nonnegative().optional().describe("Symmetric outer margin (alias for `outerSep`); axis-specific field takes precedence."),
104
- font: FontSchema.optional().describe("Font spec for the inner text label (family / size / weight / style); all fields optional, all fall back to renderer defaults.")
128
+ font: FontSchema.optional().describe("Font spec for the inner text label (family / size / weight / style); all fields optional, all fall back to renderer defaults."),
129
+ label: zod.z.union([NodeLabelSchema, zod.z.array(NodeLabelSchema)]).optional().describe("Extra label(s) attached around the node border (TikZ `[label=above:foo]`); single object or array form. Compiled into one TextPrim per label, positioned by `position` direction / angle and `distance`.")
105
130
  }).describe("Node primitive: a positioned, optionally textual shape (rectangle / circle / ellipse / diamond)");
106
131
  //#endregion
107
132
  exports.FontSchema = FontSchema;
108
133
  exports.LineSpecSchema = LineSpecSchema;
109
134
  exports.NODE_SHAPES = NODE_SHAPES;
110
135
  exports.NODE_TEXT_ALIGNS = NODE_TEXT_ALIGNS;
136
+ exports.NodeLabelSchema = NodeLabelSchema;
111
137
  exports.NodeSchema = NodeSchema;
112
138
  exports.NodeTextSchema = NodeTextSchema;