@twick/2d 0.14.0 → 1.14.3

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 (186) hide show
  1. package/LICENSE +21 -21
  2. package/editor/editor/tsconfig.build.tsbuildinfo +1 -1
  3. package/lib/components/Audio.d.ts.map +1 -1
  4. package/lib/components/Audio.js +33 -3
  5. package/lib/components/CodeBlock.d.ts +1 -1
  6. package/lib/components/Img.js +23 -23
  7. package/lib/components/Line.js +31 -31
  8. package/lib/components/Media.d.ts +6 -0
  9. package/lib/components/Media.d.ts.map +1 -1
  10. package/lib/components/Media.js +277 -61
  11. package/lib/components/Node.d.ts +1 -1
  12. package/lib/components/Path.d.ts +1 -1
  13. package/lib/components/SVG.d.ts +1 -1
  14. package/lib/components/Shape.d.ts +1 -1
  15. package/lib/components/Spline.js +25 -25
  16. package/lib/components/Video.d.ts +0 -1
  17. package/lib/components/Video.d.ts.map +1 -1
  18. package/lib/components/Video.js +70 -65
  19. package/lib/tsconfig.build.tsbuildinfo +1 -1
  20. package/package.json +4 -5
  21. package/src/editor/NodeInspectorConfig.tsx +76 -76
  22. package/src/editor/PreviewOverlayConfig.tsx +67 -67
  23. package/src/editor/Provider.tsx +93 -93
  24. package/src/editor/SceneGraphTabConfig.tsx +81 -81
  25. package/src/editor/icons/CircleIcon.tsx +7 -7
  26. package/src/editor/icons/CodeBlockIcon.tsx +8 -8
  27. package/src/editor/icons/CurveIcon.tsx +7 -7
  28. package/src/editor/icons/GridIcon.tsx +7 -7
  29. package/src/editor/icons/IconMap.ts +35 -35
  30. package/src/editor/icons/ImgIcon.tsx +8 -8
  31. package/src/editor/icons/LayoutIcon.tsx +9 -9
  32. package/src/editor/icons/LineIcon.tsx +7 -7
  33. package/src/editor/icons/NodeIcon.tsx +7 -7
  34. package/src/editor/icons/RayIcon.tsx +7 -7
  35. package/src/editor/icons/RectIcon.tsx +7 -7
  36. package/src/editor/icons/ShapeIcon.tsx +7 -7
  37. package/src/editor/icons/TxtIcon.tsx +8 -8
  38. package/src/editor/icons/VideoIcon.tsx +7 -7
  39. package/src/editor/icons/View2DIcon.tsx +10 -10
  40. package/src/editor/index.ts +17 -17
  41. package/src/editor/tree/DetachedRoot.tsx +23 -23
  42. package/src/editor/tree/NodeElement.tsx +74 -74
  43. package/src/editor/tree/TreeElement.tsx +72 -72
  44. package/src/editor/tree/TreeRoot.tsx +10 -10
  45. package/src/editor/tree/ViewRoot.tsx +20 -20
  46. package/src/editor/tree/index.module.scss +38 -38
  47. package/src/editor/tree/index.ts +3 -3
  48. package/src/editor/tsconfig.build.json +5 -5
  49. package/src/editor/tsconfig.json +12 -12
  50. package/src/editor/tsdoc.json +4 -4
  51. package/src/editor/vite-env.d.ts +1 -1
  52. package/src/lib/code/CodeCursor.ts +445 -445
  53. package/src/lib/code/CodeDiffer.ts +78 -78
  54. package/src/lib/code/CodeFragment.ts +97 -97
  55. package/src/lib/code/CodeHighlighter.ts +75 -75
  56. package/src/lib/code/CodeMetrics.ts +47 -47
  57. package/src/lib/code/CodeRange.test.ts +74 -74
  58. package/src/lib/code/CodeRange.ts +216 -216
  59. package/src/lib/code/CodeScope.ts +101 -101
  60. package/src/lib/code/CodeSelection.ts +24 -24
  61. package/src/lib/code/CodeSignal.ts +327 -327
  62. package/src/lib/code/CodeTokenizer.ts +54 -54
  63. package/src/lib/code/DefaultHighlightStyle.ts +98 -98
  64. package/src/lib/code/LezerHighlighter.ts +113 -113
  65. package/src/lib/code/diff.test.ts +311 -311
  66. package/src/lib/code/diff.ts +319 -319
  67. package/src/lib/code/extractRange.ts +126 -126
  68. package/src/lib/code/index.ts +13 -13
  69. package/src/lib/components/Audio.ts +168 -131
  70. package/src/lib/components/Bezier.ts +105 -105
  71. package/src/lib/components/Circle.ts +266 -266
  72. package/src/lib/components/Code.ts +526 -526
  73. package/src/lib/components/CodeBlock.ts +576 -576
  74. package/src/lib/components/CubicBezier.ts +112 -112
  75. package/src/lib/components/Curve.ts +455 -455
  76. package/src/lib/components/Grid.ts +135 -135
  77. package/src/lib/components/Icon.ts +96 -96
  78. package/src/lib/components/Img.ts +319 -319
  79. package/src/lib/components/Knot.ts +157 -157
  80. package/src/lib/components/Latex.ts +122 -122
  81. package/src/lib/components/Layout.ts +1092 -1092
  82. package/src/lib/components/Line.ts +429 -429
  83. package/src/lib/components/Media.ts +576 -346
  84. package/src/lib/components/Node.ts +1940 -1940
  85. package/src/lib/components/Path.ts +137 -137
  86. package/src/lib/components/Polygon.ts +171 -171
  87. package/src/lib/components/QuadBezier.ts +100 -100
  88. package/src/lib/components/Ray.ts +125 -125
  89. package/src/lib/components/Rect.ts +187 -187
  90. package/src/lib/components/Rive.ts +156 -156
  91. package/src/lib/components/SVG.ts +797 -797
  92. package/src/lib/components/Shape.ts +143 -143
  93. package/src/lib/components/Spline.ts +344 -344
  94. package/src/lib/components/Txt.test.tsx +81 -81
  95. package/src/lib/components/Txt.ts +203 -203
  96. package/src/lib/components/TxtLeaf.ts +205 -205
  97. package/src/lib/components/Video.ts +461 -462
  98. package/src/lib/components/View2D.ts +98 -98
  99. package/src/lib/components/__tests__/children.test.tsx +142 -142
  100. package/src/lib/components/__tests__/clone.test.tsx +126 -126
  101. package/src/lib/components/__tests__/generatorTest.ts +28 -28
  102. package/src/lib/components/__tests__/mockScene2D.ts +45 -45
  103. package/src/lib/components/__tests__/query.test.tsx +122 -122
  104. package/src/lib/components/__tests__/state.test.tsx +60 -60
  105. package/src/lib/components/index.ts +28 -28
  106. package/src/lib/components/types.ts +35 -35
  107. package/src/lib/curves/ArcSegment.ts +159 -159
  108. package/src/lib/curves/CircleSegment.ts +77 -77
  109. package/src/lib/curves/CubicBezierSegment.ts +78 -78
  110. package/src/lib/curves/CurveDrawingInfo.ts +11 -11
  111. package/src/lib/curves/CurvePoint.ts +15 -15
  112. package/src/lib/curves/CurveProfile.ts +7 -7
  113. package/src/lib/curves/KnotInfo.ts +10 -10
  114. package/src/lib/curves/LineSegment.ts +62 -62
  115. package/src/lib/curves/Polynomial.ts +355 -355
  116. package/src/lib/curves/Polynomial2D.ts +62 -62
  117. package/src/lib/curves/PolynomialSegment.ts +124 -124
  118. package/src/lib/curves/QuadBezierSegment.ts +64 -64
  119. package/src/lib/curves/Segment.ts +17 -17
  120. package/src/lib/curves/UniformPolynomialCurveSampler.ts +94 -94
  121. package/src/lib/curves/createCurveProfileLerp.ts +471 -471
  122. package/src/lib/curves/getBezierSplineProfile.ts +223 -223
  123. package/src/lib/curves/getCircleProfile.ts +86 -86
  124. package/src/lib/curves/getPathProfile.ts +178 -178
  125. package/src/lib/curves/getPointAtDistance.ts +21 -21
  126. package/src/lib/curves/getPolylineProfile.test.ts +21 -21
  127. package/src/lib/curves/getPolylineProfile.ts +89 -89
  128. package/src/lib/curves/getRectProfile.ts +139 -139
  129. package/src/lib/curves/index.ts +16 -16
  130. package/src/lib/decorators/canvasStyleSignal.ts +16 -16
  131. package/src/lib/decorators/colorSignal.ts +9 -9
  132. package/src/lib/decorators/compound.ts +72 -72
  133. package/src/lib/decorators/computed.ts +18 -18
  134. package/src/lib/decorators/defaultStyle.ts +18 -18
  135. package/src/lib/decorators/filtersSignal.ts +136 -136
  136. package/src/lib/decorators/index.ts +10 -10
  137. package/src/lib/decorators/initializers.ts +32 -32
  138. package/src/lib/decorators/nodeName.ts +13 -13
  139. package/src/lib/decorators/signal.test.ts +90 -90
  140. package/src/lib/decorators/signal.ts +345 -345
  141. package/src/lib/decorators/spacingSignal.ts +15 -15
  142. package/src/lib/decorators/vector2Signal.ts +30 -30
  143. package/src/lib/globals.d.ts +2 -2
  144. package/src/lib/index.ts +8 -8
  145. package/src/lib/jsx-dev-runtime.ts +2 -2
  146. package/src/lib/jsx-runtime.ts +46 -46
  147. package/src/lib/parse-svg-path.d.ts +14 -14
  148. package/src/lib/partials/Filter.ts +180 -180
  149. package/src/lib/partials/Gradient.ts +102 -102
  150. package/src/lib/partials/Pattern.ts +34 -34
  151. package/src/lib/partials/ShaderConfig.ts +117 -117
  152. package/src/lib/partials/index.ts +4 -4
  153. package/src/lib/partials/types.ts +58 -58
  154. package/src/lib/scenes/Scene2D.ts +242 -242
  155. package/src/lib/scenes/index.ts +3 -3
  156. package/src/lib/scenes/makeScene2D.ts +16 -16
  157. package/src/lib/scenes/useScene2D.ts +6 -6
  158. package/src/lib/tsconfig.build.json +5 -5
  159. package/src/lib/tsconfig.json +10 -10
  160. package/src/lib/tsdoc.json +4 -4
  161. package/src/lib/utils/CanvasUtils.ts +306 -306
  162. package/src/lib/utils/diff.test.ts +453 -453
  163. package/src/lib/utils/diff.ts +148 -148
  164. package/src/lib/utils/index.ts +2 -2
  165. package/src/lib/utils/is.ts +11 -11
  166. package/src/lib/utils/makeSignalExtensions.ts +30 -30
  167. package/src/lib/utils/video/declarations.d.ts +1 -1
  168. package/src/lib/utils/video/ffmpeg-client.ts +50 -50
  169. package/src/lib/utils/video/mp4-parser-manager.ts +72 -72
  170. package/src/lib/utils/video/parser/index.ts +1 -1
  171. package/src/lib/utils/video/parser/parser.ts +257 -257
  172. package/src/lib/utils/video/parser/sampler.ts +72 -72
  173. package/src/lib/utils/video/parser/segment.ts +302 -302
  174. package/src/lib/utils/video/parser/sink.ts +29 -29
  175. package/src/lib/utils/video/parser/utils.ts +31 -31
  176. package/src/tsconfig.base.json +19 -19
  177. package/src/tsconfig.build.json +8 -8
  178. package/src/tsconfig.json +5 -5
  179. package/tsconfig.project.json +7 -7
  180. package/lib/components/utils/waitUntil.d.ts +0 -7
  181. package/lib/components/utils/waitUntil.d.ts.map +0 -1
  182. package/lib/components/utils/waitUntil.js +0 -15
  183. package/lib/utils/waitUntil.d.ts +0 -7
  184. package/lib/utils/waitUntil.d.ts.map +0 -1
  185. package/lib/utils/waitUntil.js +0 -15
  186. package/src/lib/utils/waitUntil.ts +0 -18
@@ -1,187 +1,187 @@
1
- import type {
2
- PossibleSpacing,
3
- SerializedVector2,
4
- SignalValue,
5
- SimpleSignal,
6
- SpacingSignal,
7
- } from '@twick/core';
8
- import {BBox} from '@twick/core';
9
- import {getRectProfile} from '../curves/getRectProfile';
10
- import {computed, initial, nodeName, signal} from '../decorators';
11
- import {spacingSignal} from '../decorators/spacingSignal';
12
- import type {DesiredLength} from '../partials';
13
- import {drawRoundRect} from '../utils';
14
- import type {CurveProps} from './Curve';
15
- import {Curve} from './Curve';
16
-
17
- export interface RectProps extends CurveProps {
18
- /**
19
- * {@inheritDoc Rect.radius}
20
- */
21
- radius?: SignalValue<PossibleSpacing>;
22
-
23
- /**
24
- * {@inheritDoc Rect.smoothCorners}
25
- */
26
- smoothCorners?: SignalValue<boolean>;
27
-
28
- /**
29
- * {@inheritDoc Rect.cornerSharpness}
30
- */
31
- cornerSharpness?: SignalValue<number>;
32
- }
33
-
34
- @nodeName('Rect')
35
- export class Rect extends Curve {
36
- /**
37
- * Rounds the corners of this rectangle.
38
- *
39
- * @remarks
40
- * The value represents the radius of the quarter circle that is used to round
41
- * the corners. If the value is a number, the same radius is used for all
42
- * corners. Passing an array of two to four numbers will set individual radii
43
- * for each corner. Individual radii correspond to different corners depending
44
- * on the number of values passed:
45
- *
46
- * ```ts
47
- * // top-left-and-bottom-right | top-right-and-bottom-left
48
- * [10, 30]
49
- * // top-left | top-right-and-bottom-left | bottom-right
50
- * [10, 20, 30]
51
- * // top-left | top-right | bottom-right | bottom-left
52
- * [10, 20, 30, 40]
53
- * ```
54
- *
55
- * @example
56
- * One uniform radius:
57
- * ```tsx
58
- * <Rect
59
- * size={320}
60
- * radius={40}
61
- * fill={'white'}
62
- * />
63
- * ```
64
- * @example
65
- * Individual radii for each corner:
66
- * ```tsx
67
- * <Rect
68
- * size={320}
69
- * radius={[10, 20, 30, 40]}
70
- * fill={'white'}
71
- * />
72
- * ```
73
- */
74
- @spacingSignal('radius')
75
- public declare readonly radius: SpacingSignal<this>;
76
-
77
- /**
78
- * Enables corner smoothing.
79
- *
80
- * @remarks
81
- * This property only affects the way rounded corners are drawn. To control
82
- * the corner radius use the {@link radius} property.
83
- *
84
- * When enabled, rounded corners are drawn continuously using Bézier curves
85
- * rather than quarter circles. The sharpness of the curve can be controlled
86
- * with {@link cornerSharpness}.
87
- *
88
- * You can read more about corner smoothing in
89
- * [this article by Nick Lawrence](https://uxplanet.org/ui-ux-design-corner-smoothing-720509d1ae48).
90
- *
91
- * @example
92
- * ```tsx
93
- * <Rect
94
- * width={300}
95
- * height={300}
96
- * smoothCorners={true}
97
- * />
98
- * ```
99
- */
100
- @initial(false)
101
- @signal()
102
- public declare readonly smoothCorners: SimpleSignal<boolean, this>;
103
-
104
- /**
105
- * Controls the sharpness of {@link smoothCorners}.
106
- *
107
- * @remarks
108
- * This property only affects the way rounded corners are drawn. To control
109
- * the corner radius use the {@link radius} property.
110
- *
111
- * Requires {@link smoothCorners} to be enabled to have any effect.
112
- * By default, corner sharpness is set to `0.6` which represents a smooth,
113
- * circle-like rounding. At `0` the edges are squared off.
114
- *
115
- * @example
116
- * ```tsx
117
- * <Rect
118
- * size={300}
119
- * smoothCorners={true}
120
- * cornerSharpness={0.7}
121
- * />
122
- * ```
123
- */
124
- @initial(0.6)
125
- @signal()
126
- public declare readonly cornerSharpness: SimpleSignal<number, this>;
127
-
128
- public constructor(props: RectProps) {
129
- super(props);
130
- }
131
-
132
- @computed()
133
- public profile() {
134
- return getRectProfile(
135
- this.childrenBBox(),
136
- this.radius(),
137
- this.smoothCorners(),
138
- this.cornerSharpness(),
139
- );
140
- }
141
-
142
- protected override desiredSize(): SerializedVector2<DesiredLength> {
143
- return {
144
- x: this.width.context.getter(),
145
- y: this.height.context.getter(),
146
- };
147
- }
148
-
149
- protected override offsetComputedLayout(box: BBox): BBox {
150
- return box;
151
- }
152
-
153
- protected override childrenBBox(): BBox {
154
- return BBox.fromSizeCentered(this.computedSize());
155
- }
156
-
157
- protected override getPath(): Path2D {
158
- if (this.requiresProfile()) {
159
- return this.curveDrawingInfo().path;
160
- }
161
-
162
- const path = new Path2D();
163
- const radius = this.radius();
164
- const smoothCorners = this.smoothCorners();
165
- const cornerSharpness = this.cornerSharpness();
166
- const box = BBox.fromSizeCentered(this.size());
167
- drawRoundRect(path, box, radius, smoothCorners, cornerSharpness);
168
-
169
- return path;
170
- }
171
-
172
- protected override getCacheBBox(): BBox {
173
- return super.getCacheBBox().expand(this.rippleSize());
174
- }
175
-
176
- protected override getRipplePath(): Path2D {
177
- const path = new Path2D();
178
- const rippleSize = this.rippleSize();
179
- const radius = this.radius().addScalar(rippleSize);
180
- const smoothCorners = this.smoothCorners();
181
- const cornerSharpness = this.cornerSharpness();
182
- const box = BBox.fromSizeCentered(this.size()).expand(rippleSize);
183
- drawRoundRect(path, box, radius, smoothCorners, cornerSharpness);
184
-
185
- return path;
186
- }
187
- }
1
+ import type {
2
+ PossibleSpacing,
3
+ SerializedVector2,
4
+ SignalValue,
5
+ SimpleSignal,
6
+ SpacingSignal,
7
+ } from '@twick/core';
8
+ import {BBox} from '@twick/core';
9
+ import {getRectProfile} from '../curves/getRectProfile';
10
+ import {computed, initial, nodeName, signal} from '../decorators';
11
+ import {spacingSignal} from '../decorators/spacingSignal';
12
+ import type {DesiredLength} from '../partials';
13
+ import {drawRoundRect} from '../utils';
14
+ import type {CurveProps} from './Curve';
15
+ import {Curve} from './Curve';
16
+
17
+ export interface RectProps extends CurveProps {
18
+ /**
19
+ * {@inheritDoc Rect.radius}
20
+ */
21
+ radius?: SignalValue<PossibleSpacing>;
22
+
23
+ /**
24
+ * {@inheritDoc Rect.smoothCorners}
25
+ */
26
+ smoothCorners?: SignalValue<boolean>;
27
+
28
+ /**
29
+ * {@inheritDoc Rect.cornerSharpness}
30
+ */
31
+ cornerSharpness?: SignalValue<number>;
32
+ }
33
+
34
+ @nodeName('Rect')
35
+ export class Rect extends Curve {
36
+ /**
37
+ * Rounds the corners of this rectangle.
38
+ *
39
+ * @remarks
40
+ * The value represents the radius of the quarter circle that is used to round
41
+ * the corners. If the value is a number, the same radius is used for all
42
+ * corners. Passing an array of two to four numbers will set individual radii
43
+ * for each corner. Individual radii correspond to different corners depending
44
+ * on the number of values passed:
45
+ *
46
+ * ```ts
47
+ * // top-left-and-bottom-right | top-right-and-bottom-left
48
+ * [10, 30]
49
+ * // top-left | top-right-and-bottom-left | bottom-right
50
+ * [10, 20, 30]
51
+ * // top-left | top-right | bottom-right | bottom-left
52
+ * [10, 20, 30, 40]
53
+ * ```
54
+ *
55
+ * @example
56
+ * One uniform radius:
57
+ * ```tsx
58
+ * <Rect
59
+ * size={320}
60
+ * radius={40}
61
+ * fill={'white'}
62
+ * />
63
+ * ```
64
+ * @example
65
+ * Individual radii for each corner:
66
+ * ```tsx
67
+ * <Rect
68
+ * size={320}
69
+ * radius={[10, 20, 30, 40]}
70
+ * fill={'white'}
71
+ * />
72
+ * ```
73
+ */
74
+ @spacingSignal('radius')
75
+ public declare readonly radius: SpacingSignal<this>;
76
+
77
+ /**
78
+ * Enables corner smoothing.
79
+ *
80
+ * @remarks
81
+ * This property only affects the way rounded corners are drawn. To control
82
+ * the corner radius use the {@link radius} property.
83
+ *
84
+ * When enabled, rounded corners are drawn continuously using Bézier curves
85
+ * rather than quarter circles. The sharpness of the curve can be controlled
86
+ * with {@link cornerSharpness}.
87
+ *
88
+ * You can read more about corner smoothing in
89
+ * [this article by Nick Lawrence](https://uxplanet.org/ui-ux-design-corner-smoothing-720509d1ae48).
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * <Rect
94
+ * width={300}
95
+ * height={300}
96
+ * smoothCorners={true}
97
+ * />
98
+ * ```
99
+ */
100
+ @initial(false)
101
+ @signal()
102
+ public declare readonly smoothCorners: SimpleSignal<boolean, this>;
103
+
104
+ /**
105
+ * Controls the sharpness of {@link smoothCorners}.
106
+ *
107
+ * @remarks
108
+ * This property only affects the way rounded corners are drawn. To control
109
+ * the corner radius use the {@link radius} property.
110
+ *
111
+ * Requires {@link smoothCorners} to be enabled to have any effect.
112
+ * By default, corner sharpness is set to `0.6` which represents a smooth,
113
+ * circle-like rounding. At `0` the edges are squared off.
114
+ *
115
+ * @example
116
+ * ```tsx
117
+ * <Rect
118
+ * size={300}
119
+ * smoothCorners={true}
120
+ * cornerSharpness={0.7}
121
+ * />
122
+ * ```
123
+ */
124
+ @initial(0.6)
125
+ @signal()
126
+ public declare readonly cornerSharpness: SimpleSignal<number, this>;
127
+
128
+ public constructor(props: RectProps) {
129
+ super(props);
130
+ }
131
+
132
+ @computed()
133
+ public profile() {
134
+ return getRectProfile(
135
+ this.childrenBBox(),
136
+ this.radius(),
137
+ this.smoothCorners(),
138
+ this.cornerSharpness(),
139
+ );
140
+ }
141
+
142
+ protected override desiredSize(): SerializedVector2<DesiredLength> {
143
+ return {
144
+ x: this.width.context.getter(),
145
+ y: this.height.context.getter(),
146
+ };
147
+ }
148
+
149
+ protected override offsetComputedLayout(box: BBox): BBox {
150
+ return box;
151
+ }
152
+
153
+ protected override childrenBBox(): BBox {
154
+ return BBox.fromSizeCentered(this.computedSize());
155
+ }
156
+
157
+ protected override getPath(): Path2D {
158
+ if (this.requiresProfile()) {
159
+ return this.curveDrawingInfo().path;
160
+ }
161
+
162
+ const path = new Path2D();
163
+ const radius = this.radius();
164
+ const smoothCorners = this.smoothCorners();
165
+ const cornerSharpness = this.cornerSharpness();
166
+ const box = BBox.fromSizeCentered(this.size());
167
+ drawRoundRect(path, box, radius, smoothCorners, cornerSharpness);
168
+
169
+ return path;
170
+ }
171
+
172
+ protected override getCacheBBox(): BBox {
173
+ return super.getCacheBBox().expand(this.rippleSize());
174
+ }
175
+
176
+ protected override getRipplePath(): Path2D {
177
+ const path = new Path2D();
178
+ const rippleSize = this.rippleSize();
179
+ const radius = this.radius().addScalar(rippleSize);
180
+ const smoothCorners = this.smoothCorners();
181
+ const cornerSharpness = this.cornerSharpness();
182
+ const box = BBox.fromSizeCentered(this.size()).expand(rippleSize);
183
+ drawRoundRect(path, box, radius, smoothCorners, cornerSharpness);
184
+
185
+ return path;
186
+ }
187
+ }
@@ -1,156 +1,156 @@
1
- import type {SignalValue, SimpleSignal} from '@twick/core';
2
- import {BBox, useThread} from '@twick/core';
3
- import type {
4
- Artboard,
5
- File,
6
- LinearAnimationInstance,
7
- Renderer,
8
- RiveCanvas,
9
- } from '@rive-app/canvas-advanced';
10
- import RiveInitializer from '@rive-app/canvas-advanced';
11
- import {computed, initial, nodeName, signal} from '../decorators';
12
- import type {RectProps} from './Rect';
13
- import {Rect} from './Rect';
14
-
15
- export interface RiveProps extends RectProps {
16
- src?: SignalValue<string>;
17
- artboardId?: SignalValue<string | number>;
18
- animationId?: SignalValue<string | number>;
19
- }
20
-
21
- interface RiveInstance {
22
- rive: RiveCanvas;
23
- renderer: Renderer;
24
- artboard: Artboard;
25
- animation: LinearAnimationInstance;
26
- canvas: HTMLCanvasElement;
27
- }
28
-
29
- @nodeName('Rive')
30
- export class Rive extends Rect {
31
- @signal()
32
- public declare readonly src: SimpleSignal<string, this>;
33
-
34
- @initial(0)
35
- @signal()
36
- public declare readonly artboardId: SimpleSignal<number | string, this>;
37
-
38
- @initial(0)
39
- @signal()
40
- public declare readonly animationId: SimpleSignal<number | string, this>;
41
-
42
- @initial(0)
43
- @signal()
44
- protected declare readonly time: SimpleSignal<number, this>;
45
-
46
- protected currentTime: number = 0;
47
- protected lastTime: number = 0;
48
-
49
- public constructor(props: RiveProps) {
50
- super(props);
51
-
52
- const time = useThread().time;
53
- const start = time();
54
- this.time(() => time() - start);
55
- }
56
-
57
- @computed()
58
- private async rive(): Promise<RiveInstance> {
59
- const src = this.src();
60
- const rive = await RiveInitializer({
61
- locateFile: () => {
62
- return '/@rive-wasm';
63
- },
64
- });
65
- const canvas = document.createElement('canvas');
66
- canvas.width = this.width();
67
- canvas.height = this.height();
68
-
69
- const renderer = rive.makeRenderer(canvas);
70
- const bytes = await (await fetch(new Request(src))).arrayBuffer();
71
- const file = (await rive.load(new Uint8Array(bytes))) as File;
72
-
73
- const artboardId = this.artboardId();
74
- const artboard = this.getArtboard(artboardId, file);
75
-
76
- const animationId = this.animationId();
77
- const animation = this.getAnimation(animationId, artboard, rive);
78
-
79
- return {rive, renderer, artboard, animation, canvas};
80
- }
81
-
82
- protected override async draw(context: CanvasRenderingContext2D) {
83
- this.drawShape(context);
84
-
85
- this.currentTime = this.time();
86
- const timeToAdvance = this.currentTime - this.lastTime;
87
- this.lastTime = this.currentTime;
88
-
89
- const {rive, renderer, canvas, artboard, animation} = await this.rive();
90
- const box = BBox.fromSizeCentered(this.computedSize());
91
-
92
- const renderPromise = new Promise<void>(resolve => {
93
- function renderLoop() {
94
- renderer.clear();
95
- animation.advance(timeToAdvance);
96
- animation.apply(1);
97
-
98
- artboard.advance(timeToAdvance);
99
-
100
- renderer.save();
101
- renderer.align(
102
- rive.Fit.fill,
103
- rive.Alignment.center,
104
- {
105
- minX: 0,
106
- minY: 0,
107
- maxX: canvas.width,
108
- maxY: canvas.height,
109
- },
110
- artboard.bounds,
111
- );
112
-
113
- artboard.draw(renderer);
114
- renderer.restore();
115
- resolve();
116
- }
117
-
118
- rive.requestAnimationFrame(renderLoop);
119
- });
120
-
121
- await renderPromise;
122
-
123
- context.drawImage(canvas, box.x, box.y, box.width, box.height);
124
- if (this.clip()) {
125
- context.clip(this.getPath());
126
- }
127
-
128
- await this.drawChildren(context);
129
- }
130
-
131
- private getArtboard(artboardId: string | number, file: File): Artboard {
132
- if (typeof artboardId === 'string') {
133
- return file.artboardByName(artboardId);
134
- }
135
- if (typeof artboardId === 'number') {
136
- return file.artboardByIndex(artboardId);
137
- }
138
- return file.defaultArtboard();
139
- }
140
-
141
- private getAnimation(
142
- animationId: string | number,
143
- artboard: Artboard,
144
- rive: RiveCanvas,
145
- ): LinearAnimationInstance {
146
- let animation;
147
- if (typeof animationId === 'number') {
148
- animation = artboard.animationByIndex(animationId);
149
- } else if (typeof animationId === 'string') {
150
- animation = artboard.animationByName(animationId);
151
- } else {
152
- animation = artboard.animationByIndex(0);
153
- }
154
- return new rive.LinearAnimationInstance(animation, artboard);
155
- }
156
- }
1
+ import type {SignalValue, SimpleSignal} from '@twick/core';
2
+ import {BBox, useThread} from '@twick/core';
3
+ import type {
4
+ Artboard,
5
+ File,
6
+ LinearAnimationInstance,
7
+ Renderer,
8
+ RiveCanvas,
9
+ } from '@rive-app/canvas-advanced';
10
+ import RiveInitializer from '@rive-app/canvas-advanced';
11
+ import {computed, initial, nodeName, signal} from '../decorators';
12
+ import type {RectProps} from './Rect';
13
+ import {Rect} from './Rect';
14
+
15
+ export interface RiveProps extends RectProps {
16
+ src?: SignalValue<string>;
17
+ artboardId?: SignalValue<string | number>;
18
+ animationId?: SignalValue<string | number>;
19
+ }
20
+
21
+ interface RiveInstance {
22
+ rive: RiveCanvas;
23
+ renderer: Renderer;
24
+ artboard: Artboard;
25
+ animation: LinearAnimationInstance;
26
+ canvas: HTMLCanvasElement;
27
+ }
28
+
29
+ @nodeName('Rive')
30
+ export class Rive extends Rect {
31
+ @signal()
32
+ public declare readonly src: SimpleSignal<string, this>;
33
+
34
+ @initial(0)
35
+ @signal()
36
+ public declare readonly artboardId: SimpleSignal<number | string, this>;
37
+
38
+ @initial(0)
39
+ @signal()
40
+ public declare readonly animationId: SimpleSignal<number | string, this>;
41
+
42
+ @initial(0)
43
+ @signal()
44
+ protected declare readonly time: SimpleSignal<number, this>;
45
+
46
+ protected currentTime: number = 0;
47
+ protected lastTime: number = 0;
48
+
49
+ public constructor(props: RiveProps) {
50
+ super(props);
51
+
52
+ const time = useThread().time;
53
+ const start = time();
54
+ this.time(() => time() - start);
55
+ }
56
+
57
+ @computed()
58
+ private async rive(): Promise<RiveInstance> {
59
+ const src = this.src();
60
+ const rive = await RiveInitializer({
61
+ locateFile: () => {
62
+ return '/@rive-wasm';
63
+ },
64
+ });
65
+ const canvas = document.createElement('canvas');
66
+ canvas.width = this.width();
67
+ canvas.height = this.height();
68
+
69
+ const renderer = rive.makeRenderer(canvas);
70
+ const bytes = await (await fetch(new Request(src))).arrayBuffer();
71
+ const file = (await rive.load(new Uint8Array(bytes))) as File;
72
+
73
+ const artboardId = this.artboardId();
74
+ const artboard = this.getArtboard(artboardId, file);
75
+
76
+ const animationId = this.animationId();
77
+ const animation = this.getAnimation(animationId, artboard, rive);
78
+
79
+ return {rive, renderer, artboard, animation, canvas};
80
+ }
81
+
82
+ protected override async draw(context: CanvasRenderingContext2D) {
83
+ this.drawShape(context);
84
+
85
+ this.currentTime = this.time();
86
+ const timeToAdvance = this.currentTime - this.lastTime;
87
+ this.lastTime = this.currentTime;
88
+
89
+ const {rive, renderer, canvas, artboard, animation} = await this.rive();
90
+ const box = BBox.fromSizeCentered(this.computedSize());
91
+
92
+ const renderPromise = new Promise<void>(resolve => {
93
+ function renderLoop() {
94
+ renderer.clear();
95
+ animation.advance(timeToAdvance);
96
+ animation.apply(1);
97
+
98
+ artboard.advance(timeToAdvance);
99
+
100
+ renderer.save();
101
+ renderer.align(
102
+ rive.Fit.fill,
103
+ rive.Alignment.center,
104
+ {
105
+ minX: 0,
106
+ minY: 0,
107
+ maxX: canvas.width,
108
+ maxY: canvas.height,
109
+ },
110
+ artboard.bounds,
111
+ );
112
+
113
+ artboard.draw(renderer);
114
+ renderer.restore();
115
+ resolve();
116
+ }
117
+
118
+ rive.requestAnimationFrame(renderLoop);
119
+ });
120
+
121
+ await renderPromise;
122
+
123
+ context.drawImage(canvas, box.x, box.y, box.width, box.height);
124
+ if (this.clip()) {
125
+ context.clip(this.getPath());
126
+ }
127
+
128
+ await this.drawChildren(context);
129
+ }
130
+
131
+ private getArtboard(artboardId: string | number, file: File): Artboard {
132
+ if (typeof artboardId === 'string') {
133
+ return file.artboardByName(artboardId);
134
+ }
135
+ if (typeof artboardId === 'number') {
136
+ return file.artboardByIndex(artboardId);
137
+ }
138
+ return file.defaultArtboard();
139
+ }
140
+
141
+ private getAnimation(
142
+ animationId: string | number,
143
+ artboard: Artboard,
144
+ rive: RiveCanvas,
145
+ ): LinearAnimationInstance {
146
+ let animation;
147
+ if (typeof animationId === 'number') {
148
+ animation = artboard.animationByIndex(animationId);
149
+ } else if (typeof animationId === 'string') {
150
+ animation = artboard.animationByName(animationId);
151
+ } else {
152
+ animation = artboard.animationByIndex(0);
153
+ }
154
+ return new rive.LinearAnimationInstance(animation, artboard);
155
+ }
156
+ }