@canvas-commons/2d 0.2.0

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 (183) hide show
  1. package/LICENSE +22 -0
  2. package/editor/index.css +40 -0
  3. package/editor/index.js +525 -0
  4. package/editor/index.js.map +1 -0
  5. package/lib/index-OvpZ-GsA.d.ts +5673 -0
  6. package/lib/index-OvpZ-GsA.d.ts.map +1 -0
  7. package/lib/index.d.ts +2 -0
  8. package/lib/index.js +10326 -0
  9. package/lib/index.js.map +1 -0
  10. package/lib/jsx-dev-runtime.d.ts +2 -0
  11. package/lib/jsx-dev-runtime.js +2 -0
  12. package/lib/jsx-runtime.d.ts +2 -0
  13. package/lib/jsx-runtime.js +28 -0
  14. package/lib/jsx-runtime.js.map +1 -0
  15. package/package.json +79 -0
  16. package/src/editor/NodeInspectorConfig.tsx +76 -0
  17. package/src/editor/PreviewOverlayConfig.tsx +65 -0
  18. package/src/editor/Provider.tsx +109 -0
  19. package/src/editor/SceneGraphTabConfig.tsx +87 -0
  20. package/src/editor/icons/CircleIcon.tsx +7 -0
  21. package/src/editor/icons/CodeIcon.tsx +8 -0
  22. package/src/editor/icons/CurveIcon.tsx +7 -0
  23. package/src/editor/icons/GridIcon.tsx +7 -0
  24. package/src/editor/icons/IconMap.ts +35 -0
  25. package/src/editor/icons/ImgIcon.tsx +8 -0
  26. package/src/editor/icons/LayoutIcon.tsx +9 -0
  27. package/src/editor/icons/LineIcon.tsx +7 -0
  28. package/src/editor/icons/NodeIcon.tsx +7 -0
  29. package/src/editor/icons/RayIcon.tsx +7 -0
  30. package/src/editor/icons/RectIcon.tsx +7 -0
  31. package/src/editor/icons/ShapeIcon.tsx +7 -0
  32. package/src/editor/icons/TxtIcon.tsx +8 -0
  33. package/src/editor/icons/VideoIcon.tsx +7 -0
  34. package/src/editor/icons/View2DIcon.tsx +10 -0
  35. package/src/editor/index.css +0 -0
  36. package/src/editor/index.ts +19 -0
  37. package/src/editor/shortcuts.ts +27 -0
  38. package/src/editor/tree/DetachedRoot.tsx +27 -0
  39. package/src/editor/tree/NodeElement.tsx +72 -0
  40. package/src/editor/tree/TreeElement.tsx +70 -0
  41. package/src/editor/tree/TreeRoot.tsx +10 -0
  42. package/src/editor/tree/ViewRoot.tsx +20 -0
  43. package/src/editor/tree/index.module.scss +45 -0
  44. package/src/editor/tree/index.ts +4 -0
  45. package/src/editor/tree/navigation.ts +145 -0
  46. package/src/editor/tsconfig.build.json +5 -0
  47. package/src/editor/tsconfig.json +12 -0
  48. package/src/editor/tsdoc.json +4 -0
  49. package/src/editor/utils/SignalSet.ts +37 -0
  50. package/src/editor/utils/index.ts +1 -0
  51. package/src/editor/vite-env.d.ts +1 -0
  52. package/src/lib/code/CodeCursor.ts +468 -0
  53. package/src/lib/code/CodeDiffer.ts +77 -0
  54. package/src/lib/code/CodeFragment.ts +96 -0
  55. package/src/lib/code/CodeHighlighter.ts +73 -0
  56. package/src/lib/code/CodeMetrics.ts +47 -0
  57. package/src/lib/code/CodeRange.test.ts +113 -0
  58. package/src/lib/code/CodeRange.ts +222 -0
  59. package/src/lib/code/CodeScope.ts +100 -0
  60. package/src/lib/code/CodeSelection.ts +28 -0
  61. package/src/lib/code/CodeSignal.ts +348 -0
  62. package/src/lib/code/CodeTokenizer.ts +54 -0
  63. package/src/lib/code/DefaultHighlightStyle.ts +98 -0
  64. package/src/lib/code/LezerHighlighter.ts +113 -0
  65. package/src/lib/code/diff.test.ts +311 -0
  66. package/src/lib/code/diff.ts +319 -0
  67. package/src/lib/code/extractRange.ts +125 -0
  68. package/src/lib/code/index.ts +13 -0
  69. package/src/lib/components/Bezier.ts +103 -0
  70. package/src/lib/components/Camera.ts +401 -0
  71. package/src/lib/components/Circle.ts +310 -0
  72. package/src/lib/components/Code.ts +532 -0
  73. package/src/lib/components/CubicBezier.ts +115 -0
  74. package/src/lib/components/Curve.ts +460 -0
  75. package/src/lib/components/Grid.ts +134 -0
  76. package/src/lib/components/Icon.ts +153 -0
  77. package/src/lib/components/Img.ts +328 -0
  78. package/src/lib/components/Knot.ts +156 -0
  79. package/src/lib/components/Latex.ts +537 -0
  80. package/src/lib/components/Layout.ts +1101 -0
  81. package/src/lib/components/Line.ts +394 -0
  82. package/src/lib/components/Node.ts +1941 -0
  83. package/src/lib/components/Path.ts +132 -0
  84. package/src/lib/components/Polygon.ts +266 -0
  85. package/src/lib/components/QuadBezier.ts +103 -0
  86. package/src/lib/components/Ray.ts +126 -0
  87. package/src/lib/components/Rect.ts +219 -0
  88. package/src/lib/components/SVG.ts +853 -0
  89. package/src/lib/components/Shape.ts +322 -0
  90. package/src/lib/components/Spline.ts +318 -0
  91. package/src/lib/components/Txt.test.tsx +81 -0
  92. package/src/lib/components/Txt.ts +204 -0
  93. package/src/lib/components/TxtLeaf.ts +210 -0
  94. package/src/lib/components/Video.ts +368 -0
  95. package/src/lib/components/View2D.ts +85 -0
  96. package/src/lib/components/__logs__/image-without-source.ts +18 -0
  97. package/src/lib/components/__logs__/line-without-points.ts +31 -0
  98. package/src/lib/components/__logs__/reactive-playback-rate.ts +22 -0
  99. package/src/lib/components/__logs__/spline-with-insufficient-knots.ts +25 -0
  100. package/src/lib/components/__tests__/Camera.test.tsx +73 -0
  101. package/src/lib/components/__tests__/children.test.tsx +142 -0
  102. package/src/lib/components/__tests__/clone.test.tsx +126 -0
  103. package/src/lib/components/__tests__/fontInheritance.test.tsx +102 -0
  104. package/src/lib/components/__tests__/generatorTest.ts +27 -0
  105. package/src/lib/components/__tests__/mockScene2D.ts +50 -0
  106. package/src/lib/components/__tests__/query.test.tsx +122 -0
  107. package/src/lib/components/__tests__/state.test.tsx +60 -0
  108. package/src/lib/components/index.ts +26 -0
  109. package/src/lib/components/types.ts +35 -0
  110. package/src/lib/curves/ArcSegment.ts +169 -0
  111. package/src/lib/curves/CircleSegment.ts +99 -0
  112. package/src/lib/curves/CubicBezierSegment.ts +80 -0
  113. package/src/lib/curves/CurveDrawingInfo.ts +11 -0
  114. package/src/lib/curves/CurvePoint.ts +15 -0
  115. package/src/lib/curves/CurveProfile.ts +28 -0
  116. package/src/lib/curves/KnotInfo.ts +10 -0
  117. package/src/lib/curves/LineSegment.ts +75 -0
  118. package/src/lib/curves/Polynomial.ts +355 -0
  119. package/src/lib/curves/Polynomial2D.ts +62 -0
  120. package/src/lib/curves/PolynomialSegment.ts +151 -0
  121. package/src/lib/curves/QuadBezierSegment.ts +66 -0
  122. package/src/lib/curves/Segment.ts +31 -0
  123. package/src/lib/curves/UniformPolynomialCurveSampler.ts +93 -0
  124. package/src/lib/curves/createCurveProfileLerp.ts +471 -0
  125. package/src/lib/curves/getBezierSplineProfile.ts +227 -0
  126. package/src/lib/curves/getCircleProfile.ts +86 -0
  127. package/src/lib/curves/getPathProfile.ts +177 -0
  128. package/src/lib/curves/getPointAtDistance.ts +21 -0
  129. package/src/lib/curves/getPolylineProfile.test.ts +21 -0
  130. package/src/lib/curves/getPolylineProfile.ts +88 -0
  131. package/src/lib/curves/getRectProfile.ts +138 -0
  132. package/src/lib/curves/index.ts +16 -0
  133. package/src/lib/decorators/canvasStyleSignal.ts +15 -0
  134. package/src/lib/decorators/colorSignal.ts +9 -0
  135. package/src/lib/decorators/compound.ts +85 -0
  136. package/src/lib/decorators/computed.ts +18 -0
  137. package/src/lib/decorators/defaultStyle.ts +15 -0
  138. package/src/lib/decorators/filtersSignal.ts +133 -0
  139. package/src/lib/decorators/index.ts +10 -0
  140. package/src/lib/decorators/initializers.ts +32 -0
  141. package/src/lib/decorators/nodeName.ts +13 -0
  142. package/src/lib/decorators/signal.test.ts +89 -0
  143. package/src/lib/decorators/signal.ts +348 -0
  144. package/src/lib/decorators/spacingSignal.ts +15 -0
  145. package/src/lib/decorators/transformSignals.test.ts +858 -0
  146. package/src/lib/decorators/transformSignals.ts +1633 -0
  147. package/src/lib/decorators/vector2Signal.ts +35 -0
  148. package/src/lib/globals.d.ts +2 -0
  149. package/src/lib/index.ts +9 -0
  150. package/src/lib/jsx-dev-runtime.ts +2 -0
  151. package/src/lib/jsx-runtime.ts +45 -0
  152. package/src/lib/morphers/PathMorpher.ts +8 -0
  153. package/src/lib/morphers/defaultMorpher.ts +43 -0
  154. package/src/lib/morphers/index.ts +4 -0
  155. package/src/lib/morphers/manimMorpher.ts +658 -0
  156. package/src/lib/parse-svg-path.d.ts +14 -0
  157. package/src/lib/partials/Filter.ts +185 -0
  158. package/src/lib/partials/Gradient.ts +103 -0
  159. package/src/lib/partials/Pattern.ts +35 -0
  160. package/src/lib/partials/RoughConfig.ts +180 -0
  161. package/src/lib/partials/ShaderConfig.ts +122 -0
  162. package/src/lib/partials/index.ts +5 -0
  163. package/src/lib/partials/types.ts +58 -0
  164. package/src/lib/scenes/Scene2D.ts +167 -0
  165. package/src/lib/scenes/index.ts +3 -0
  166. package/src/lib/scenes/makeScene2D.ts +19 -0
  167. package/src/lib/scenes/useScene2D.ts +6 -0
  168. package/src/lib/tsconfig.build.json +5 -0
  169. package/src/lib/tsconfig.json +11 -0
  170. package/src/lib/tsdoc.json +4 -0
  171. package/src/lib/utils/CanvasUtils.ts +304 -0
  172. package/src/lib/utils/PathDataBuilder.ts +320 -0
  173. package/src/lib/utils/diff.test.ts +453 -0
  174. package/src/lib/utils/diff.ts +148 -0
  175. package/src/lib/utils/index.ts +5 -0
  176. package/src/lib/utils/is.ts +11 -0
  177. package/src/lib/utils/makeSignalExtensions.ts +29 -0
  178. package/src/lib/utils/rough.ts +513 -0
  179. package/src/lib/utils/withDefaults.tsx +26 -0
  180. package/src/tsconfig.base.json +18 -0
  181. package/src/tsconfig.build.json +8 -0
  182. package/src/tsconfig.json +5 -0
  183. package/tsconfig.project.json +7 -0
@@ -0,0 +1,320 @@
1
+ import {Vector2} from '@canvas-commons/core';
2
+
3
+ /**
4
+ * A builder for constructing SVG path data strings.
5
+ *
6
+ * @remarks
7
+ * This class provides a fluent API for building SVG path data, which can be
8
+ * used to create Path2D objects or passed to other renderers like Rough.js.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const builder = new PathDataBuilder();
13
+ * builder.moveTo(0, 0).lineTo(100, 100).closePath();
14
+ * const pathData = builder.toString(); // "M 0 0 L 100 100 Z"
15
+ * const path = new Path2D(pathData);
16
+ * ```
17
+ */
18
+ export class PathDataBuilder {
19
+ private commands: string[] = [];
20
+
21
+ /**
22
+ * Move to a point without drawing.
23
+ *
24
+ * @param x - The x coordinate
25
+ * @param y - The y coordinate
26
+ */
27
+ public moveTo(x: number, y: number): this {
28
+ this.commands.push(`M ${x} ${y}`);
29
+ return this;
30
+ }
31
+
32
+ /**
33
+ * Draw a line to a point.
34
+ *
35
+ * @param x - The x coordinate
36
+ * @param y - The y coordinate
37
+ */
38
+ public lineTo(x: number, y: number): this {
39
+ this.commands.push(`L ${x} ${y}`);
40
+ return this;
41
+ }
42
+
43
+ /**
44
+ * Draw a cubic Bezier curve.
45
+ *
46
+ * @param cp1x - First control point x
47
+ * @param cp1y - First control point y
48
+ * @param cp2x - Second control point x
49
+ * @param cp2y - Second control point y
50
+ * @param x - End point x
51
+ * @param y - End point y
52
+ */
53
+ public bezierCurveTo(
54
+ cp1x: number,
55
+ cp1y: number,
56
+ cp2x: number,
57
+ cp2y: number,
58
+ x: number,
59
+ y: number,
60
+ ): this {
61
+ this.commands.push(`C ${cp1x} ${cp1y} ${cp2x} ${cp2y} ${x} ${y}`);
62
+ return this;
63
+ }
64
+
65
+ /**
66
+ * Draw a quadratic Bezier curve.
67
+ *
68
+ * @param cpx - Control point x
69
+ * @param cpy - Control point y
70
+ * @param x - End point x
71
+ * @param y - End point y
72
+ */
73
+ public quadraticCurveTo(
74
+ cpx: number,
75
+ cpy: number,
76
+ x: number,
77
+ y: number,
78
+ ): this {
79
+ this.commands.push(`Q ${cpx} ${cpy} ${x} ${y}`);
80
+ return this;
81
+ }
82
+
83
+ /**
84
+ * Draw an elliptical arc.
85
+ *
86
+ * @remarks
87
+ * Converts canvas ellipse parameters to SVG arc commands. For full ellipses,
88
+ * this generates two arc commands to work around SVG's limitation of 180-degree
89
+ * maximum arc sweeps.
90
+ *
91
+ * @param x - Center x coordinate
92
+ * @param y - Center y coordinate
93
+ * @param radiusX - Horizontal radius
94
+ * @param radiusY - Vertical radius
95
+ * @param rotation - Rotation angle in radians
96
+ * @param startAngle - Start angle in radians
97
+ * @param endAngle - End angle in radians
98
+ * @param counterclockwise - Whether to draw counterclockwise
99
+ */
100
+ public ellipse(
101
+ x: number,
102
+ y: number,
103
+ radiusX: number,
104
+ radiusY: number,
105
+ rotation: number,
106
+ startAngle: number,
107
+ endAngle: number,
108
+ counterclockwise = false,
109
+ ): this {
110
+ const start = startAngle;
111
+ const end = endAngle;
112
+
113
+ let angleDiff = end - start;
114
+ if (counterclockwise && angleDiff > 0) {
115
+ angleDiff -= 2 * Math.PI;
116
+ } else if (!counterclockwise && angleDiff < 0) {
117
+ angleDiff += 2 * Math.PI;
118
+ }
119
+
120
+ const startPoint = Vector2.fromRadians(start).mul(
121
+ new Vector2(radiusX, radiusY),
122
+ );
123
+ const rotatedStart = startPoint.rotate(rotation);
124
+ const startX = x + rotatedStart.x;
125
+ const startY = y + rotatedStart.y;
126
+
127
+ const endPoint = Vector2.fromRadians(end).mul(
128
+ new Vector2(radiusX, radiusY),
129
+ );
130
+ const rotatedEnd = endPoint.rotate(rotation);
131
+ const endX = x + rotatedEnd.x;
132
+ const endY = y + rotatedEnd.y;
133
+
134
+ if (this.commands.length === 0) {
135
+ this.moveTo(startX, startY);
136
+ } else {
137
+ this.lineTo(startX, startY);
138
+ }
139
+
140
+ // Determine if this is a large arc (> 180 degrees)
141
+ const largeArc = Math.abs(angleDiff) > Math.PI ? 1 : 0;
142
+ const sweep = counterclockwise ? 0 : 1;
143
+
144
+ // Convert rotation from radians to degrees
145
+ const rotationDeg = (rotation * 180) / Math.PI;
146
+
147
+ if (Math.abs(Math.abs(angleDiff) - 2 * Math.PI) < 0.001) {
148
+ const midAngle = start + angleDiff / 2;
149
+ const midPoint = Vector2.fromRadians(midAngle).mul(
150
+ new Vector2(radiusX, radiusY),
151
+ );
152
+ const rotatedMid = midPoint.rotate(rotation);
153
+ const midX = x + rotatedMid.x;
154
+ const midY = y + rotatedMid.y;
155
+
156
+ this.commands.push(
157
+ `A ${radiusX} ${radiusY} ${rotationDeg} 0 ${sweep} ${midX} ${midY}`,
158
+ );
159
+ this.commands.push(
160
+ `A ${radiusX} ${radiusY} ${rotationDeg} 0 ${sweep} ${endX} ${endY}`,
161
+ );
162
+ } else {
163
+ // Partial arc
164
+ this.commands.push(
165
+ `A ${radiusX} ${radiusY} ${rotationDeg} ${largeArc} ${sweep} ${endX} ${endY}`,
166
+ );
167
+ }
168
+
169
+ return this;
170
+ }
171
+
172
+ /**
173
+ * Draw a circular arc using the arc command.
174
+ *
175
+ * @remarks
176
+ * This is a convenience method that calls {@link ellipse} with equal radii.
177
+ *
178
+ * @param x - Center x coordinate
179
+ * @param y - Center y coordinate
180
+ * @param radius - Arc radius
181
+ * @param startAngle - Start angle in radians
182
+ * @param endAngle - End angle in radians
183
+ * @param counterclockwise - Whether to draw counterclockwise
184
+ */
185
+ public arc(
186
+ x: number,
187
+ y: number,
188
+ radius: number,
189
+ startAngle: number,
190
+ endAngle: number,
191
+ counterclockwise = false,
192
+ ): this {
193
+ return this.ellipse(
194
+ x,
195
+ y,
196
+ radius,
197
+ radius,
198
+ 0,
199
+ startAngle,
200
+ endAngle,
201
+ counterclockwise,
202
+ );
203
+ }
204
+
205
+ /**
206
+ * Draw an arc to a point with a given radius.
207
+ *
208
+ * @remarks
209
+ * This matches the Canvas API's arcTo method. It draws a straight line from
210
+ * the current point to the start of an arc, then draws an arc with the given
211
+ * radius that is tangent to the line from the current point to (x1, y1) and
212
+ * the line from (x1, y1) to (x2, y2).
213
+ *
214
+ * @param x1 - First control point x
215
+ * @param y1 - First control point y
216
+ * @param x2 - Second control point x
217
+ * @param y2 - Second control point y
218
+ * @param radius - Arc radius
219
+ */
220
+ public arcTo(
221
+ x1: number,
222
+ y1: number,
223
+ x2: number,
224
+ y2: number,
225
+ radius: number,
226
+ ): this {
227
+ if (this.commands.length === 0) {
228
+ this.moveTo(x1, y1);
229
+ return this;
230
+ }
231
+
232
+ const lastCommand = this.commands[this.commands.length - 1];
233
+ const coords = lastCommand.split(' ').slice(1).map(Number);
234
+ const p0 = new Vector2(
235
+ coords[coords.length - 2],
236
+ coords[coords.length - 1],
237
+ );
238
+ const p1 = new Vector2(x1, y1);
239
+ const p2 = new Vector2(x2, y2);
240
+
241
+ const v1 = p0.sub(p1);
242
+ const v2 = p2.sub(p1);
243
+
244
+ const v1Length = v1.magnitude;
245
+ const v2Length = v2.magnitude;
246
+
247
+ if (v1Length === 0 || v2Length === 0) {
248
+ this.lineTo(x1, y1);
249
+ return this;
250
+ }
251
+
252
+ const v1n = v1.normalized;
253
+ const v2n = v2.normalized;
254
+
255
+ const angle = Math.acos(v1n.dot(v2n));
256
+
257
+ if (Math.abs(angle) < 0.0001 || Math.abs(angle - Math.PI) < 0.0001) {
258
+ this.lineTo(x1, y1);
259
+ return this;
260
+ }
261
+
262
+ const tangentLength = radius / Math.tan(angle / 2);
263
+
264
+ const t1 = p1.add(v1n.scale(tangentLength));
265
+ const t2 = p1.add(v2n.scale(tangentLength));
266
+
267
+ this.lineTo(t1.x, t1.y);
268
+
269
+ const bisector = v1n.add(v2n).normalized;
270
+ const centerDistance = radius / Math.sin(angle / 2);
271
+ const center = p1.add(bisector.scale(centerDistance));
272
+
273
+ const startAngle = Math.atan2(t1.y - center.y, t1.x - center.x);
274
+ const endAngle = Math.atan2(t2.y - center.y, t2.x - center.x);
275
+
276
+ let angleDiff = endAngle - startAngle;
277
+ const cross = v1n.x * v2n.y - v1n.y * v2n.x;
278
+ const counterclockwise = cross > 0;
279
+
280
+ if (counterclockwise && angleDiff > 0) {
281
+ angleDiff -= 2 * Math.PI;
282
+ } else if (!counterclockwise && angleDiff < 0) {
283
+ angleDiff += 2 * Math.PI;
284
+ }
285
+
286
+ const largeArc = Math.abs(angleDiff) > Math.PI ? 1 : 0;
287
+ const sweep = counterclockwise ? 0 : 1;
288
+
289
+ this.commands.push(
290
+ `A ${radius} ${radius} 0 ${largeArc} ${sweep} ${t2.x} ${t2.y}`,
291
+ );
292
+
293
+ return this;
294
+ }
295
+
296
+ /**
297
+ * Close the current path.
298
+ */
299
+ public closePath(): this {
300
+ this.commands.push('Z');
301
+ return this;
302
+ }
303
+
304
+ /**
305
+ * Get the SVG path data string.
306
+ *
307
+ * @returns The complete SVG path data
308
+ */
309
+ public toString(): string {
310
+ return this.commands.join(' ');
311
+ }
312
+
313
+ /**
314
+ * Reset the builder to empty state.
315
+ */
316
+ public clear(): this {
317
+ this.commands = [];
318
+ return this;
319
+ }
320
+ }