@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.
- package/LICENSE +21 -21
- package/editor/editor/tsconfig.build.tsbuildinfo +1 -1
- package/lib/components/Audio.d.ts.map +1 -1
- package/lib/components/Audio.js +33 -3
- package/lib/components/CodeBlock.d.ts +1 -1
- package/lib/components/Img.js +23 -23
- package/lib/components/Line.js +31 -31
- package/lib/components/Media.d.ts +6 -0
- package/lib/components/Media.d.ts.map +1 -1
- package/lib/components/Media.js +277 -61
- package/lib/components/Node.d.ts +1 -1
- package/lib/components/Path.d.ts +1 -1
- package/lib/components/SVG.d.ts +1 -1
- package/lib/components/Shape.d.ts +1 -1
- package/lib/components/Spline.js +25 -25
- package/lib/components/Video.d.ts +0 -1
- package/lib/components/Video.d.ts.map +1 -1
- package/lib/components/Video.js +70 -65
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -5
- package/src/editor/NodeInspectorConfig.tsx +76 -76
- package/src/editor/PreviewOverlayConfig.tsx +67 -67
- package/src/editor/Provider.tsx +93 -93
- package/src/editor/SceneGraphTabConfig.tsx +81 -81
- package/src/editor/icons/CircleIcon.tsx +7 -7
- package/src/editor/icons/CodeBlockIcon.tsx +8 -8
- package/src/editor/icons/CurveIcon.tsx +7 -7
- package/src/editor/icons/GridIcon.tsx +7 -7
- package/src/editor/icons/IconMap.ts +35 -35
- package/src/editor/icons/ImgIcon.tsx +8 -8
- package/src/editor/icons/LayoutIcon.tsx +9 -9
- package/src/editor/icons/LineIcon.tsx +7 -7
- package/src/editor/icons/NodeIcon.tsx +7 -7
- package/src/editor/icons/RayIcon.tsx +7 -7
- package/src/editor/icons/RectIcon.tsx +7 -7
- package/src/editor/icons/ShapeIcon.tsx +7 -7
- package/src/editor/icons/TxtIcon.tsx +8 -8
- package/src/editor/icons/VideoIcon.tsx +7 -7
- package/src/editor/icons/View2DIcon.tsx +10 -10
- package/src/editor/index.ts +17 -17
- package/src/editor/tree/DetachedRoot.tsx +23 -23
- package/src/editor/tree/NodeElement.tsx +74 -74
- package/src/editor/tree/TreeElement.tsx +72 -72
- package/src/editor/tree/TreeRoot.tsx +10 -10
- package/src/editor/tree/ViewRoot.tsx +20 -20
- package/src/editor/tree/index.module.scss +38 -38
- package/src/editor/tree/index.ts +3 -3
- package/src/editor/tsconfig.build.json +5 -5
- package/src/editor/tsconfig.json +12 -12
- package/src/editor/tsdoc.json +4 -4
- package/src/editor/vite-env.d.ts +1 -1
- package/src/lib/code/CodeCursor.ts +445 -445
- package/src/lib/code/CodeDiffer.ts +78 -78
- package/src/lib/code/CodeFragment.ts +97 -97
- package/src/lib/code/CodeHighlighter.ts +75 -75
- package/src/lib/code/CodeMetrics.ts +47 -47
- package/src/lib/code/CodeRange.test.ts +74 -74
- package/src/lib/code/CodeRange.ts +216 -216
- package/src/lib/code/CodeScope.ts +101 -101
- package/src/lib/code/CodeSelection.ts +24 -24
- package/src/lib/code/CodeSignal.ts +327 -327
- package/src/lib/code/CodeTokenizer.ts +54 -54
- package/src/lib/code/DefaultHighlightStyle.ts +98 -98
- package/src/lib/code/LezerHighlighter.ts +113 -113
- package/src/lib/code/diff.test.ts +311 -311
- package/src/lib/code/diff.ts +319 -319
- package/src/lib/code/extractRange.ts +126 -126
- package/src/lib/code/index.ts +13 -13
- package/src/lib/components/Audio.ts +168 -131
- package/src/lib/components/Bezier.ts +105 -105
- package/src/lib/components/Circle.ts +266 -266
- package/src/lib/components/Code.ts +526 -526
- package/src/lib/components/CodeBlock.ts +576 -576
- package/src/lib/components/CubicBezier.ts +112 -112
- package/src/lib/components/Curve.ts +455 -455
- package/src/lib/components/Grid.ts +135 -135
- package/src/lib/components/Icon.ts +96 -96
- package/src/lib/components/Img.ts +319 -319
- package/src/lib/components/Knot.ts +157 -157
- package/src/lib/components/Latex.ts +122 -122
- package/src/lib/components/Layout.ts +1092 -1092
- package/src/lib/components/Line.ts +429 -429
- package/src/lib/components/Media.ts +576 -346
- package/src/lib/components/Node.ts +1940 -1940
- package/src/lib/components/Path.ts +137 -137
- package/src/lib/components/Polygon.ts +171 -171
- package/src/lib/components/QuadBezier.ts +100 -100
- package/src/lib/components/Ray.ts +125 -125
- package/src/lib/components/Rect.ts +187 -187
- package/src/lib/components/Rive.ts +156 -156
- package/src/lib/components/SVG.ts +797 -797
- package/src/lib/components/Shape.ts +143 -143
- package/src/lib/components/Spline.ts +344 -344
- package/src/lib/components/Txt.test.tsx +81 -81
- package/src/lib/components/Txt.ts +203 -203
- package/src/lib/components/TxtLeaf.ts +205 -205
- package/src/lib/components/Video.ts +461 -462
- package/src/lib/components/View2D.ts +98 -98
- package/src/lib/components/__tests__/children.test.tsx +142 -142
- package/src/lib/components/__tests__/clone.test.tsx +126 -126
- package/src/lib/components/__tests__/generatorTest.ts +28 -28
- package/src/lib/components/__tests__/mockScene2D.ts +45 -45
- package/src/lib/components/__tests__/query.test.tsx +122 -122
- package/src/lib/components/__tests__/state.test.tsx +60 -60
- package/src/lib/components/index.ts +28 -28
- package/src/lib/components/types.ts +35 -35
- package/src/lib/curves/ArcSegment.ts +159 -159
- package/src/lib/curves/CircleSegment.ts +77 -77
- package/src/lib/curves/CubicBezierSegment.ts +78 -78
- package/src/lib/curves/CurveDrawingInfo.ts +11 -11
- package/src/lib/curves/CurvePoint.ts +15 -15
- package/src/lib/curves/CurveProfile.ts +7 -7
- package/src/lib/curves/KnotInfo.ts +10 -10
- package/src/lib/curves/LineSegment.ts +62 -62
- package/src/lib/curves/Polynomial.ts +355 -355
- package/src/lib/curves/Polynomial2D.ts +62 -62
- package/src/lib/curves/PolynomialSegment.ts +124 -124
- package/src/lib/curves/QuadBezierSegment.ts +64 -64
- package/src/lib/curves/Segment.ts +17 -17
- package/src/lib/curves/UniformPolynomialCurveSampler.ts +94 -94
- package/src/lib/curves/createCurveProfileLerp.ts +471 -471
- package/src/lib/curves/getBezierSplineProfile.ts +223 -223
- package/src/lib/curves/getCircleProfile.ts +86 -86
- package/src/lib/curves/getPathProfile.ts +178 -178
- package/src/lib/curves/getPointAtDistance.ts +21 -21
- package/src/lib/curves/getPolylineProfile.test.ts +21 -21
- package/src/lib/curves/getPolylineProfile.ts +89 -89
- package/src/lib/curves/getRectProfile.ts +139 -139
- package/src/lib/curves/index.ts +16 -16
- package/src/lib/decorators/canvasStyleSignal.ts +16 -16
- package/src/lib/decorators/colorSignal.ts +9 -9
- package/src/lib/decorators/compound.ts +72 -72
- package/src/lib/decorators/computed.ts +18 -18
- package/src/lib/decorators/defaultStyle.ts +18 -18
- package/src/lib/decorators/filtersSignal.ts +136 -136
- package/src/lib/decorators/index.ts +10 -10
- package/src/lib/decorators/initializers.ts +32 -32
- package/src/lib/decorators/nodeName.ts +13 -13
- package/src/lib/decorators/signal.test.ts +90 -90
- package/src/lib/decorators/signal.ts +345 -345
- package/src/lib/decorators/spacingSignal.ts +15 -15
- package/src/lib/decorators/vector2Signal.ts +30 -30
- package/src/lib/globals.d.ts +2 -2
- package/src/lib/index.ts +8 -8
- package/src/lib/jsx-dev-runtime.ts +2 -2
- package/src/lib/jsx-runtime.ts +46 -46
- package/src/lib/parse-svg-path.d.ts +14 -14
- package/src/lib/partials/Filter.ts +180 -180
- package/src/lib/partials/Gradient.ts +102 -102
- package/src/lib/partials/Pattern.ts +34 -34
- package/src/lib/partials/ShaderConfig.ts +117 -117
- package/src/lib/partials/index.ts +4 -4
- package/src/lib/partials/types.ts +58 -58
- package/src/lib/scenes/Scene2D.ts +242 -242
- package/src/lib/scenes/index.ts +3 -3
- package/src/lib/scenes/makeScene2D.ts +16 -16
- package/src/lib/scenes/useScene2D.ts +6 -6
- package/src/lib/tsconfig.build.json +5 -5
- package/src/lib/tsconfig.json +10 -10
- package/src/lib/tsdoc.json +4 -4
- package/src/lib/utils/CanvasUtils.ts +306 -306
- package/src/lib/utils/diff.test.ts +453 -453
- package/src/lib/utils/diff.ts +148 -148
- package/src/lib/utils/index.ts +2 -2
- package/src/lib/utils/is.ts +11 -11
- package/src/lib/utils/makeSignalExtensions.ts +30 -30
- package/src/lib/utils/video/declarations.d.ts +1 -1
- package/src/lib/utils/video/ffmpeg-client.ts +50 -50
- package/src/lib/utils/video/mp4-parser-manager.ts +72 -72
- package/src/lib/utils/video/parser/index.ts +1 -1
- package/src/lib/utils/video/parser/parser.ts +257 -257
- package/src/lib/utils/video/parser/sampler.ts +72 -72
- package/src/lib/utils/video/parser/segment.ts +302 -302
- package/src/lib/utils/video/parser/sink.ts +29 -29
- package/src/lib/utils/video/parser/utils.ts +31 -31
- package/src/tsconfig.base.json +19 -19
- package/src/tsconfig.build.json +8 -8
- package/src/tsconfig.json +5 -5
- package/tsconfig.project.json +7 -7
- package/lib/components/utils/waitUntil.d.ts +0 -7
- package/lib/components/utils/waitUntil.d.ts.map +0 -1
- package/lib/components/utils/waitUntil.js +0 -15
- package/lib/utils/waitUntil.d.ts +0 -7
- package/lib/utils/waitUntil.d.ts.map +0 -1
- package/lib/utils/waitUntil.js +0 -15
- package/src/lib/utils/waitUntil.ts +0 -18
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
import type {SimpleSignal} from '@twick/core';
|
|
2
|
-
import {PlaybackState, lazy} from '@twick/core';
|
|
3
|
-
import {initial, signal} from '../decorators';
|
|
4
|
-
import {nodeName} from '../decorators/nodeName';
|
|
5
|
-
import {useScene2D} from '../scenes/useScene2D';
|
|
6
|
-
import type {Node} from './Node';
|
|
7
|
-
import type {RectProps} from './Rect';
|
|
8
|
-
import {Rect} from './Rect';
|
|
9
|
-
|
|
10
|
-
export interface View2DProps extends RectProps {
|
|
11
|
-
assetHash: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
@nodeName('View2D')
|
|
15
|
-
export class View2D extends Rect {
|
|
16
|
-
// TODO: scope this to individual player
|
|
17
|
-
@lazy(() => {
|
|
18
|
-
const frameID = 'twick-2d-frame';
|
|
19
|
-
let frame = document.querySelector<HTMLDivElement>(`#${frameID}`);
|
|
20
|
-
if (!frame) {
|
|
21
|
-
frame = document.createElement('div');
|
|
22
|
-
frame.id = frameID;
|
|
23
|
-
frame.style.position = 'absolute';
|
|
24
|
-
frame.style.pointerEvents = 'none';
|
|
25
|
-
frame.style.top = '0';
|
|
26
|
-
frame.style.left = '0';
|
|
27
|
-
frame.style.fontFeatureSettings = 'normal'; // TODO: find solution that fully isolates CSS
|
|
28
|
-
frame.style.opacity = '0';
|
|
29
|
-
frame.style.overflow = 'hidden';
|
|
30
|
-
document.body.prepend(frame);
|
|
31
|
-
}
|
|
32
|
-
return frame.shadowRoot ?? frame.attachShadow({mode: 'open'});
|
|
33
|
-
})
|
|
34
|
-
public static shadowRoot: ShadowRoot;
|
|
35
|
-
|
|
36
|
-
@initial(PlaybackState.Paused)
|
|
37
|
-
@signal()
|
|
38
|
-
public declare readonly playbackState: SimpleSignal<PlaybackState, this>;
|
|
39
|
-
|
|
40
|
-
@initial(0)
|
|
41
|
-
@signal()
|
|
42
|
-
public declare readonly globalTime: SimpleSignal<number, this>;
|
|
43
|
-
|
|
44
|
-
@initial(0)
|
|
45
|
-
@signal()
|
|
46
|
-
public declare readonly fps: SimpleSignal<number, this>;
|
|
47
|
-
|
|
48
|
-
@signal()
|
|
49
|
-
public declare readonly assetHash: SimpleSignal<string, this>;
|
|
50
|
-
|
|
51
|
-
public constructor(props: View2DProps) {
|
|
52
|
-
super({
|
|
53
|
-
composite: true,
|
|
54
|
-
fontFamily: 'Roboto',
|
|
55
|
-
fontSize: 48,
|
|
56
|
-
lineHeight: '120%',
|
|
57
|
-
textWrap: false,
|
|
58
|
-
fontStyle: 'normal',
|
|
59
|
-
...props,
|
|
60
|
-
});
|
|
61
|
-
this.view2D = this;
|
|
62
|
-
|
|
63
|
-
View2D.shadowRoot.append(this.element);
|
|
64
|
-
this.applyFlex();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public override dispose() {
|
|
68
|
-
this.removeChildren();
|
|
69
|
-
super.dispose();
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
public override async render(context: CanvasRenderingContext2D) {
|
|
73
|
-
this.computedSize();
|
|
74
|
-
this.computedPosition();
|
|
75
|
-
await super.render(context);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Find a node by its key.
|
|
80
|
-
*
|
|
81
|
-
* @param key - The key of the node.
|
|
82
|
-
*/
|
|
83
|
-
public findKey<T extends Node = Node>(key: string): T | null {
|
|
84
|
-
return (useScene2D().getNode(key) as T) ?? null;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
protected override requestLayoutUpdate() {
|
|
88
|
-
this.updateLayout();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
protected override requestFontUpdate() {
|
|
92
|
-
this.applyFont();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
public override view(): View2D {
|
|
96
|
-
return this;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
1
|
+
import type {SimpleSignal} from '@twick/core';
|
|
2
|
+
import {PlaybackState, lazy} from '@twick/core';
|
|
3
|
+
import {initial, signal} from '../decorators';
|
|
4
|
+
import {nodeName} from '../decorators/nodeName';
|
|
5
|
+
import {useScene2D} from '../scenes/useScene2D';
|
|
6
|
+
import type {Node} from './Node';
|
|
7
|
+
import type {RectProps} from './Rect';
|
|
8
|
+
import {Rect} from './Rect';
|
|
9
|
+
|
|
10
|
+
export interface View2DProps extends RectProps {
|
|
11
|
+
assetHash: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
@nodeName('View2D')
|
|
15
|
+
export class View2D extends Rect {
|
|
16
|
+
// TODO: scope this to individual player
|
|
17
|
+
@lazy(() => {
|
|
18
|
+
const frameID = 'twick-2d-frame';
|
|
19
|
+
let frame = document.querySelector<HTMLDivElement>(`#${frameID}`);
|
|
20
|
+
if (!frame) {
|
|
21
|
+
frame = document.createElement('div');
|
|
22
|
+
frame.id = frameID;
|
|
23
|
+
frame.style.position = 'absolute';
|
|
24
|
+
frame.style.pointerEvents = 'none';
|
|
25
|
+
frame.style.top = '0';
|
|
26
|
+
frame.style.left = '0';
|
|
27
|
+
frame.style.fontFeatureSettings = 'normal'; // TODO: find solution that fully isolates CSS
|
|
28
|
+
frame.style.opacity = '0';
|
|
29
|
+
frame.style.overflow = 'hidden';
|
|
30
|
+
document.body.prepend(frame);
|
|
31
|
+
}
|
|
32
|
+
return frame.shadowRoot ?? frame.attachShadow({mode: 'open'});
|
|
33
|
+
})
|
|
34
|
+
public static shadowRoot: ShadowRoot;
|
|
35
|
+
|
|
36
|
+
@initial(PlaybackState.Paused)
|
|
37
|
+
@signal()
|
|
38
|
+
public declare readonly playbackState: SimpleSignal<PlaybackState, this>;
|
|
39
|
+
|
|
40
|
+
@initial(0)
|
|
41
|
+
@signal()
|
|
42
|
+
public declare readonly globalTime: SimpleSignal<number, this>;
|
|
43
|
+
|
|
44
|
+
@initial(0)
|
|
45
|
+
@signal()
|
|
46
|
+
public declare readonly fps: SimpleSignal<number, this>;
|
|
47
|
+
|
|
48
|
+
@signal()
|
|
49
|
+
public declare readonly assetHash: SimpleSignal<string, this>;
|
|
50
|
+
|
|
51
|
+
public constructor(props: View2DProps) {
|
|
52
|
+
super({
|
|
53
|
+
composite: true,
|
|
54
|
+
fontFamily: 'Roboto',
|
|
55
|
+
fontSize: 48,
|
|
56
|
+
lineHeight: '120%',
|
|
57
|
+
textWrap: false,
|
|
58
|
+
fontStyle: 'normal',
|
|
59
|
+
...props,
|
|
60
|
+
});
|
|
61
|
+
this.view2D = this;
|
|
62
|
+
|
|
63
|
+
View2D.shadowRoot.append(this.element);
|
|
64
|
+
this.applyFlex();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public override dispose() {
|
|
68
|
+
this.removeChildren();
|
|
69
|
+
super.dispose();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public override async render(context: CanvasRenderingContext2D) {
|
|
73
|
+
this.computedSize();
|
|
74
|
+
this.computedPosition();
|
|
75
|
+
await super.render(context);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Find a node by its key.
|
|
80
|
+
*
|
|
81
|
+
* @param key - The key of the node.
|
|
82
|
+
*/
|
|
83
|
+
public findKey<T extends Node = Node>(key: string): T | null {
|
|
84
|
+
return (useScene2D().getNode(key) as T) ?? null;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
protected override requestLayoutUpdate() {
|
|
88
|
+
this.updateLayout();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected override requestFontUpdate() {
|
|
92
|
+
this.applyFont();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public override view(): View2D {
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -1,142 +1,142 @@
|
|
|
1
|
-
import {createRef, createSignal, range} from '@twick/core';
|
|
2
|
-
import {describe, expect, it} from 'vitest';
|
|
3
|
-
import {useScene2D} from '../../scenes';
|
|
4
|
-
import {Node} from '../Node';
|
|
5
|
-
import {mockScene2D} from './mockScene2D';
|
|
6
|
-
|
|
7
|
-
describe('children', () => {
|
|
8
|
-
mockScene2D();
|
|
9
|
-
|
|
10
|
-
it('Append children', () => {
|
|
11
|
-
const view = useScene2D().getView();
|
|
12
|
-
const parent = createRef<Node>();
|
|
13
|
-
const childA = createRef<Node>();
|
|
14
|
-
const childB = createRef<Node>();
|
|
15
|
-
|
|
16
|
-
view.add(
|
|
17
|
-
<Node ref={parent}>
|
|
18
|
-
<Node ref={childA} />
|
|
19
|
-
<Node ref={childB} />
|
|
20
|
-
</Node>,
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
expect(childA().parent()).toBe(parent());
|
|
24
|
-
expect(childB().parent()).toBe(parent());
|
|
25
|
-
expect(parent().children()).toEqual([childA(), childB()]);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('Clear children', () => {
|
|
29
|
-
const view = useScene2D().getView();
|
|
30
|
-
const parent = createRef<Node>();
|
|
31
|
-
const childA = createRef<Node>();
|
|
32
|
-
const childB = createRef<Node>();
|
|
33
|
-
|
|
34
|
-
view.add(
|
|
35
|
-
<Node ref={parent}>
|
|
36
|
-
<Node ref={childA} />
|
|
37
|
-
<Node ref={childB} />
|
|
38
|
-
</Node>,
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
parent().removeChildren();
|
|
42
|
-
|
|
43
|
-
expect(childA().parent()).toBe(null);
|
|
44
|
-
expect(childB().parent()).toBe(null);
|
|
45
|
-
expect(parent().children()).toEqual([]);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('Replace children', () => {
|
|
49
|
-
const view = useScene2D().getView();
|
|
50
|
-
const parent = createRef<Node>();
|
|
51
|
-
const childA = <Node />;
|
|
52
|
-
const childB = <Node />;
|
|
53
|
-
|
|
54
|
-
view.add(<Node ref={parent}>{childA}</Node>);
|
|
55
|
-
|
|
56
|
-
parent().children(childB);
|
|
57
|
-
|
|
58
|
-
expect(childA.parent()).toBe(null);
|
|
59
|
-
expect(childB.parent()).toBe(parent());
|
|
60
|
-
expect(parent().children()).toEqual([childB]);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('Take a child from another node', () => {
|
|
64
|
-
const view = useScene2D().getView();
|
|
65
|
-
const parentA = createRef<Node>();
|
|
66
|
-
const parentB = createRef<Node>();
|
|
67
|
-
const child = createRef<Node>();
|
|
68
|
-
|
|
69
|
-
view.add(
|
|
70
|
-
<>
|
|
71
|
-
<Node ref={parentA}>
|
|
72
|
-
<Node ref={child} />
|
|
73
|
-
</Node>
|
|
74
|
-
<Node ref={parentB} />
|
|
75
|
-
</>,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
expect(parentA().children()).toEqual([child()]);
|
|
79
|
-
expect(parentB().children()).toEqual([]);
|
|
80
|
-
expect(child().parent()).toBe(parentA());
|
|
81
|
-
|
|
82
|
-
parentB().children(child());
|
|
83
|
-
|
|
84
|
-
expect(parentA().children()).toEqual([]);
|
|
85
|
-
expect(parentB().children()).toEqual([child()]);
|
|
86
|
-
expect(child().parent()).toBe(parentB());
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
it('Append children conditionally', () => {
|
|
90
|
-
const view = useScene2D().getView();
|
|
91
|
-
const parent = createRef<Node>();
|
|
92
|
-
const childA = <Node />;
|
|
93
|
-
const childB = <Node />;
|
|
94
|
-
const predicate = createSignal(false);
|
|
95
|
-
|
|
96
|
-
view.add(<Node ref={parent}>{() => (predicate() ? childA : childB)}</Node>);
|
|
97
|
-
|
|
98
|
-
expect(parent().children()).toEqual([childB]);
|
|
99
|
-
expect(childA.parent()).toBe(null);
|
|
100
|
-
expect(childB.parent()).toBe(parent());
|
|
101
|
-
|
|
102
|
-
predicate(true);
|
|
103
|
-
|
|
104
|
-
expect(parent().children()).toEqual([childA]);
|
|
105
|
-
expect(childA.parent()).toBe(parent());
|
|
106
|
-
expect(childB.parent()).toBe(null);
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it('Spawn reactive children', () => {
|
|
110
|
-
const view = useScene2D().getView();
|
|
111
|
-
const parent = createRef<Node>();
|
|
112
|
-
const count = createSignal(3);
|
|
113
|
-
|
|
114
|
-
view.add(
|
|
115
|
-
<Node ref={parent}>{() => range(count()).map(() => <Node />)}</Node>,
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
expect(parent().children().length).toBe(3);
|
|
119
|
-
|
|
120
|
-
count(5);
|
|
121
|
-
|
|
122
|
-
expect(parent().children().length).toBe(5);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('Replace a spawner', () => {
|
|
126
|
-
const view = useScene2D().getView();
|
|
127
|
-
const parent = createRef<Node>();
|
|
128
|
-
const childA = <Node />;
|
|
129
|
-
const childB = <Node />;
|
|
130
|
-
|
|
131
|
-
view.add(<Node ref={parent}>{() => childA}</Node>);
|
|
132
|
-
|
|
133
|
-
expect(parent().children()).toEqual([childA]);
|
|
134
|
-
expect(childA.parent()).toBe(parent());
|
|
135
|
-
|
|
136
|
-
parent().children(childB);
|
|
137
|
-
|
|
138
|
-
expect(childA.parent()).toBe(null);
|
|
139
|
-
expect(childB.parent()).toBe(parent());
|
|
140
|
-
expect(parent().children()).toEqual([childB]);
|
|
141
|
-
});
|
|
142
|
-
});
|
|
1
|
+
import {createRef, createSignal, range} from '@twick/core';
|
|
2
|
+
import {describe, expect, it} from 'vitest';
|
|
3
|
+
import {useScene2D} from '../../scenes';
|
|
4
|
+
import {Node} from '../Node';
|
|
5
|
+
import {mockScene2D} from './mockScene2D';
|
|
6
|
+
|
|
7
|
+
describe('children', () => {
|
|
8
|
+
mockScene2D();
|
|
9
|
+
|
|
10
|
+
it('Append children', () => {
|
|
11
|
+
const view = useScene2D().getView();
|
|
12
|
+
const parent = createRef<Node>();
|
|
13
|
+
const childA = createRef<Node>();
|
|
14
|
+
const childB = createRef<Node>();
|
|
15
|
+
|
|
16
|
+
view.add(
|
|
17
|
+
<Node ref={parent}>
|
|
18
|
+
<Node ref={childA} />
|
|
19
|
+
<Node ref={childB} />
|
|
20
|
+
</Node>,
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
expect(childA().parent()).toBe(parent());
|
|
24
|
+
expect(childB().parent()).toBe(parent());
|
|
25
|
+
expect(parent().children()).toEqual([childA(), childB()]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('Clear children', () => {
|
|
29
|
+
const view = useScene2D().getView();
|
|
30
|
+
const parent = createRef<Node>();
|
|
31
|
+
const childA = createRef<Node>();
|
|
32
|
+
const childB = createRef<Node>();
|
|
33
|
+
|
|
34
|
+
view.add(
|
|
35
|
+
<Node ref={parent}>
|
|
36
|
+
<Node ref={childA} />
|
|
37
|
+
<Node ref={childB} />
|
|
38
|
+
</Node>,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
parent().removeChildren();
|
|
42
|
+
|
|
43
|
+
expect(childA().parent()).toBe(null);
|
|
44
|
+
expect(childB().parent()).toBe(null);
|
|
45
|
+
expect(parent().children()).toEqual([]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('Replace children', () => {
|
|
49
|
+
const view = useScene2D().getView();
|
|
50
|
+
const parent = createRef<Node>();
|
|
51
|
+
const childA = <Node />;
|
|
52
|
+
const childB = <Node />;
|
|
53
|
+
|
|
54
|
+
view.add(<Node ref={parent}>{childA}</Node>);
|
|
55
|
+
|
|
56
|
+
parent().children(childB);
|
|
57
|
+
|
|
58
|
+
expect(childA.parent()).toBe(null);
|
|
59
|
+
expect(childB.parent()).toBe(parent());
|
|
60
|
+
expect(parent().children()).toEqual([childB]);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('Take a child from another node', () => {
|
|
64
|
+
const view = useScene2D().getView();
|
|
65
|
+
const parentA = createRef<Node>();
|
|
66
|
+
const parentB = createRef<Node>();
|
|
67
|
+
const child = createRef<Node>();
|
|
68
|
+
|
|
69
|
+
view.add(
|
|
70
|
+
<>
|
|
71
|
+
<Node ref={parentA}>
|
|
72
|
+
<Node ref={child} />
|
|
73
|
+
</Node>
|
|
74
|
+
<Node ref={parentB} />
|
|
75
|
+
</>,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
expect(parentA().children()).toEqual([child()]);
|
|
79
|
+
expect(parentB().children()).toEqual([]);
|
|
80
|
+
expect(child().parent()).toBe(parentA());
|
|
81
|
+
|
|
82
|
+
parentB().children(child());
|
|
83
|
+
|
|
84
|
+
expect(parentA().children()).toEqual([]);
|
|
85
|
+
expect(parentB().children()).toEqual([child()]);
|
|
86
|
+
expect(child().parent()).toBe(parentB());
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('Append children conditionally', () => {
|
|
90
|
+
const view = useScene2D().getView();
|
|
91
|
+
const parent = createRef<Node>();
|
|
92
|
+
const childA = <Node />;
|
|
93
|
+
const childB = <Node />;
|
|
94
|
+
const predicate = createSignal(false);
|
|
95
|
+
|
|
96
|
+
view.add(<Node ref={parent}>{() => (predicate() ? childA : childB)}</Node>);
|
|
97
|
+
|
|
98
|
+
expect(parent().children()).toEqual([childB]);
|
|
99
|
+
expect(childA.parent()).toBe(null);
|
|
100
|
+
expect(childB.parent()).toBe(parent());
|
|
101
|
+
|
|
102
|
+
predicate(true);
|
|
103
|
+
|
|
104
|
+
expect(parent().children()).toEqual([childA]);
|
|
105
|
+
expect(childA.parent()).toBe(parent());
|
|
106
|
+
expect(childB.parent()).toBe(null);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('Spawn reactive children', () => {
|
|
110
|
+
const view = useScene2D().getView();
|
|
111
|
+
const parent = createRef<Node>();
|
|
112
|
+
const count = createSignal(3);
|
|
113
|
+
|
|
114
|
+
view.add(
|
|
115
|
+
<Node ref={parent}>{() => range(count()).map(() => <Node />)}</Node>,
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
expect(parent().children().length).toBe(3);
|
|
119
|
+
|
|
120
|
+
count(5);
|
|
121
|
+
|
|
122
|
+
expect(parent().children().length).toBe(5);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('Replace a spawner', () => {
|
|
126
|
+
const view = useScene2D().getView();
|
|
127
|
+
const parent = createRef<Node>();
|
|
128
|
+
const childA = <Node />;
|
|
129
|
+
const childB = <Node />;
|
|
130
|
+
|
|
131
|
+
view.add(<Node ref={parent}>{() => childA}</Node>);
|
|
132
|
+
|
|
133
|
+
expect(parent().children()).toEqual([childA]);
|
|
134
|
+
expect(childA.parent()).toBe(parent());
|
|
135
|
+
|
|
136
|
+
parent().children(childB);
|
|
137
|
+
|
|
138
|
+
expect(childA.parent()).toBe(null);
|
|
139
|
+
expect(childB.parent()).toBe(parent());
|
|
140
|
+
expect(parent().children()).toEqual([childB]);
|
|
141
|
+
});
|
|
142
|
+
});
|