canvasengine 2.0.0-beta.16 → 2.0.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +55 -25
- package/dist/index.js +361 -238
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/src/components/Canvas.ts +53 -45
- package/src/components/Container.ts +2 -2
- package/src/components/DisplayObject.ts +232 -173
- package/src/components/Graphic.ts +18 -7
- package/src/components/NineSliceSprite.ts +4 -1
- package/src/components/ParticleEmitter.ts +12 -8
- package/src/components/Sprite.ts +7 -4
- package/src/components/Text.ts +26 -10
- package/src/components/Viewport.ts +53 -31
- package/src/components/types/DisplayObject.ts +22 -0
- package/src/directives/ViewportFollow.ts +1 -1
- package/src/engine/bootstrap.ts +14 -2
- package/src/engine/reactive.ts +5 -4
- package/src/index.ts +1 -0
- package/src/utils/functions.ts +7 -0
- package/testing/index.ts +3 -2
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import { Node } from "yoga-layout";
|
|
2
1
|
import { Element, isElement, Props } from "../engine/reactive";
|
|
3
2
|
import { setObservablePoint } from "../engine/utils";
|
|
4
3
|
import type {
|
|
5
4
|
AlignContent,
|
|
6
5
|
EdgeSize,
|
|
7
6
|
FlexDirection,
|
|
8
|
-
|
|
7
|
+
ObjectFit,
|
|
8
|
+
ObjectPosition,
|
|
9
|
+
TransformOrigin,
|
|
9
10
|
} from "./types/DisplayObject";
|
|
10
|
-
import {
|
|
11
|
+
import { signal } from "@signe/reactive";
|
|
11
12
|
import { DropShadowFilter } from "pixi-filters";
|
|
12
13
|
import { BlurFilter, ObservablePoint } from "pixi.js";
|
|
14
|
+
import { isPercent } from "../utils/functions";
|
|
13
15
|
|
|
14
16
|
export interface ComponentInstance extends PixiMixins.ContainerOptions {
|
|
15
17
|
id?: string;
|
|
16
18
|
children?: ComponentInstance[];
|
|
17
19
|
onInit?(props: Props): void;
|
|
18
20
|
onUpdate?(props: Props): void;
|
|
19
|
-
onDestroy?(parent: Element): void;
|
|
21
|
+
onDestroy?(parent: Element, afterDestroy: () => void): void;
|
|
20
22
|
onMount?(context: Element, index?: number): void;
|
|
21
23
|
setWidth(width: number): void;
|
|
22
24
|
setHeight(height: number): void;
|
|
@@ -93,6 +95,8 @@ export const EVENTS = [
|
|
|
93
95
|
"wheelcapture",
|
|
94
96
|
];
|
|
95
97
|
|
|
98
|
+
type OnHook = (() => void) | (() => Promise<void> | void);
|
|
99
|
+
|
|
96
100
|
export function DisplayObject(extendClass) {
|
|
97
101
|
return class DisplayObject extends extendClass {
|
|
98
102
|
#canvasContext: {
|
|
@@ -101,20 +105,14 @@ export function DisplayObject(extendClass) {
|
|
|
101
105
|
isFlex: boolean = false;
|
|
102
106
|
fullProps: Props = {};
|
|
103
107
|
isMounted: boolean = false;
|
|
104
|
-
_anchorPoints = new ObservablePoint(
|
|
105
|
-
{ _onUpdate: () => {} },
|
|
106
|
-
0,
|
|
107
|
-
0
|
|
108
|
-
);
|
|
108
|
+
_anchorPoints = new ObservablePoint({ _onUpdate: () => {} }, 0, 0);
|
|
109
109
|
isCustomAnchor: boolean = false;
|
|
110
110
|
displayWidth = signal(0);
|
|
111
111
|
displayHeight = signal(0);
|
|
112
112
|
overrideProps: string[] = [];
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return this.#canvasContext?.Yoga;
|
|
117
|
-
}
|
|
113
|
+
layout = null;
|
|
114
|
+
onBeforeDestroy: OnHook | null = null;
|
|
115
|
+
onAfterMount: OnHook | null = null;
|
|
118
116
|
|
|
119
117
|
get deltaRatio() {
|
|
120
118
|
return this.#canvasContext?.scheduler?.tick.value.deltaRatio;
|
|
@@ -128,80 +126,45 @@ export function DisplayObject(extendClass) {
|
|
|
128
126
|
this.on(event, props[event]);
|
|
129
127
|
}
|
|
130
128
|
}
|
|
129
|
+
if (props.onBeforeDestroy || props['on-before-destroy']) {
|
|
130
|
+
this.onBeforeDestroy = props.onBeforeDestroy || props['on-before-destroy'];
|
|
131
|
+
}
|
|
132
|
+
if (props.onAfterMount || props['on-after-mount']) {
|
|
133
|
+
this.onAfterMount = props.onAfterMount || props['on-after-mount'];
|
|
134
|
+
}
|
|
135
|
+
if (
|
|
136
|
+
props.justifyContent ||
|
|
137
|
+
props.alignItems ||
|
|
138
|
+
props.flexDirection ||
|
|
139
|
+
props.flexWrap ||
|
|
140
|
+
props.alignContent ||
|
|
141
|
+
props.display == "flex" ||
|
|
142
|
+
isPercent(props.width) ||
|
|
143
|
+
isPercent(props.height) ||
|
|
144
|
+
props.isRoot
|
|
145
|
+
) {
|
|
146
|
+
this.layout = {};
|
|
147
|
+
this.isFlex = true;
|
|
148
|
+
}
|
|
131
149
|
}
|
|
132
150
|
|
|
133
|
-
onMount({ parent, props }: Element<DisplayObject>, index?: number) {
|
|
151
|
+
async onMount({ parent, props }: Element<DisplayObject>, index?: number) {
|
|
134
152
|
this.#canvasContext = props.context;
|
|
135
|
-
this.node = this.yoga.Node.create();
|
|
136
153
|
if (parent) {
|
|
137
154
|
const instance = parent.componentInstance as DisplayObject;
|
|
155
|
+
if (instance.isFlex && !this.layout) {
|
|
156
|
+
this.layout = {};
|
|
157
|
+
}
|
|
138
158
|
if (index === undefined) {
|
|
139
159
|
instance.addChild(this);
|
|
140
160
|
} else {
|
|
141
161
|
instance.addChildAt(this, index);
|
|
142
162
|
}
|
|
143
|
-
if (instance.layer) this.parentLayer = instance.layer;
|
|
144
163
|
this.isMounted = true;
|
|
145
|
-
this.effectSize(props.width, props.height);
|
|
146
164
|
this.onUpdate(props);
|
|
147
|
-
this.
|
|
148
|
-
this.
|
|
149
|
-
this.parent.node.getChildCount()
|
|
150
|
-
);
|
|
151
|
-
if (parent.props.flexDirection) {
|
|
152
|
-
this.parent.node.calculateLayout();
|
|
153
|
-
for (let child of this.parent.children) {
|
|
154
|
-
const { left, top } = child.getComputedLayout();
|
|
155
|
-
child.x = left;
|
|
156
|
-
child.y = top;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
effectSize(width: Size, height: Size) {
|
|
164
|
-
const handleSize = (
|
|
165
|
-
size: Size,
|
|
166
|
-
setter: (value: number) => void,
|
|
167
|
-
parentSize: Signal<number>
|
|
168
|
-
) => {
|
|
169
|
-
if (typeof size === "string" && size.endsWith("%")) {
|
|
170
|
-
effect(() => {
|
|
171
|
-
setter(parentSize() * (parseInt(size) / 100));
|
|
172
|
-
if (this.isFlex) {
|
|
173
|
-
this.applyFlexLayout();
|
|
174
|
-
}
|
|
175
|
-
});
|
|
176
|
-
} else {
|
|
177
|
-
setter(+size);
|
|
165
|
+
if (this.onAfterMount) {
|
|
166
|
+
await this.onAfterMount();
|
|
178
167
|
}
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
if (width != undefined)
|
|
182
|
-
handleSize(width, this.setWidth.bind(this), this.parent.displayWidth);
|
|
183
|
-
if (height != undefined)
|
|
184
|
-
handleSize(
|
|
185
|
-
height,
|
|
186
|
-
this.setHeight.bind(this),
|
|
187
|
-
this.parent.displayHeight
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
applyFlexLayout() {
|
|
192
|
-
this.calculateLayout();
|
|
193
|
-
for (let child of this.children) {
|
|
194
|
-
const { left, top } = child.node.getComputedLayout();
|
|
195
|
-
child.x = left;
|
|
196
|
-
child.y = top;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
#flexRender(props) {
|
|
201
|
-
if (!this.parent) return;
|
|
202
|
-
if (props.flexDirection || props.justifyContent) {
|
|
203
|
-
this.isFlex = true;
|
|
204
|
-
this.applyFlexLayout();
|
|
205
168
|
}
|
|
206
169
|
}
|
|
207
170
|
|
|
@@ -212,6 +175,7 @@ export function DisplayObject(extendClass) {
|
|
|
212
175
|
};
|
|
213
176
|
|
|
214
177
|
if (!this.#canvasContext || !this.parent) return;
|
|
178
|
+
|
|
215
179
|
if (props.x !== undefined) this.setX(props.x);
|
|
216
180
|
if (props.y !== undefined) this.setY(props.y);
|
|
217
181
|
if (props.scale !== undefined)
|
|
@@ -219,6 +183,28 @@ export function DisplayObject(extendClass) {
|
|
|
219
183
|
if (props.anchor !== undefined && !this.isCustomAnchor) {
|
|
220
184
|
setObservablePoint(this.anchor, props.anchor);
|
|
221
185
|
}
|
|
186
|
+
if (props.width !== undefined) this.setWidth(props.width);
|
|
187
|
+
if (props.height !== undefined) this.setHeight(props.height);
|
|
188
|
+
if (props.minWidth !== undefined) this.setMinWidth(props.minWidth);
|
|
189
|
+
if (props.minHeight !== undefined) this.setMinHeight(props.minHeight);
|
|
190
|
+
if (props.maxWidth !== undefined) this.setMaxWidth(props.maxWidth);
|
|
191
|
+
if (props.maxHeight !== undefined) this.setMaxHeight(props.maxHeight);
|
|
192
|
+
if (props.aspectRatio !== undefined)
|
|
193
|
+
this.setAspectRatio(props.aspectRatio);
|
|
194
|
+
if (props.flexGrow !== undefined) this.setFlexGrow(props.flexGrow);
|
|
195
|
+
if (props.flexShrink !== undefined) this.setFlexShrink(props.flexShrink);
|
|
196
|
+
if (props.flexBasis !== undefined) this.setFlexBasis(props.flexBasis);
|
|
197
|
+
if (props.rowGap !== undefined) this.setRowGap(props.rowGap);
|
|
198
|
+
if (props.columnGap !== undefined) this.setColumnGap(props.columnGap);
|
|
199
|
+
if (props.top !== undefined) this.setTop(props.top);
|
|
200
|
+
if (props.left !== undefined) this.setLeft(props.left);
|
|
201
|
+
if (props.right !== undefined) this.setRight(props.right);
|
|
202
|
+
if (props.bottom !== undefined) this.setBottom(props.bottom);
|
|
203
|
+
if (props.objectFit !== undefined) this.setObjectFit(props.objectFit);
|
|
204
|
+
if (props.objectPosition !== undefined)
|
|
205
|
+
this.setObjectPosition(props.objectPosition);
|
|
206
|
+
if (props.transformOrigin !== undefined)
|
|
207
|
+
this.setTransformOrigin(props.transformOrigin);
|
|
222
208
|
if (props.skew !== undefined) setObservablePoint(this.skew, props.skew);
|
|
223
209
|
if (props.tint) this.tint = props.tint;
|
|
224
210
|
if (props.rotation !== undefined) this.rotation = props.rotation;
|
|
@@ -279,73 +265,34 @@ export function DisplayObject(extendClass) {
|
|
|
279
265
|
}
|
|
280
266
|
|
|
281
267
|
this.filters = currentFilters;
|
|
282
|
-
|
|
283
|
-
this.#flexRender(props);
|
|
284
268
|
}
|
|
285
269
|
|
|
286
|
-
onDestroy() {
|
|
270
|
+
async onDestroy(parent: Element, afterDestroy?: () => void) {
|
|
271
|
+
if (this.onBeforeDestroy) {
|
|
272
|
+
await this.onBeforeDestroy();
|
|
273
|
+
}
|
|
287
274
|
super.destroy();
|
|
288
|
-
this.
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
getComputedLayout() {
|
|
292
|
-
return this.node.getComputedLayout();
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
applyComputedLayout() {
|
|
296
|
-
const layout = this.getComputedLayout();
|
|
297
|
-
this.x = layout.left;
|
|
298
|
-
this.y = layout.top;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
calculateLayout() {
|
|
302
|
-
this.node.calculateLayout();
|
|
275
|
+
if (this.onAfterDestroy) this.onAfterDestroy()
|
|
303
276
|
}
|
|
304
277
|
|
|
305
278
|
setFlexDirection(direction: FlexDirection) {
|
|
306
|
-
|
|
307
|
-
row: this.yoga.FLEX_DIRECTION_ROW,
|
|
308
|
-
column: this.yoga.FLEX_DIRECTION_COLUMN,
|
|
309
|
-
"row-reverse": this.yoga.FLEX_DIRECTION_ROW_REVERSE,
|
|
310
|
-
"column-reverse": this.yoga.FLEX_DIRECTION_COLUMN_REVERSE,
|
|
311
|
-
};
|
|
312
|
-
this.node.setFlexDirection(mapping[direction]);
|
|
279
|
+
this.layout = { flexDirection: direction };
|
|
313
280
|
}
|
|
314
281
|
|
|
315
282
|
setFlexWrap(wrap: "wrap" | "nowrap" | "wrap-reverse") {
|
|
316
|
-
|
|
317
|
-
wrap: this.yoga.WRAP_WRAP,
|
|
318
|
-
nowrap: this.yoga.WRAP_NO_WRAP,
|
|
319
|
-
"wrap-reverse": this.yoga.WRAP_WRAP_REVERSE,
|
|
320
|
-
};
|
|
321
|
-
this.node.setFlexWrap(mapping[wrap]);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
#setAlign(methodName: string, align: AlignContent) {
|
|
325
|
-
const mapping = {
|
|
326
|
-
auto: this.yoga.ALIGN_AUTO,
|
|
327
|
-
"flex-start": this.yoga.ALIGN_FLEX_START,
|
|
328
|
-
"flex-end": this.yoga.ALIGN_FLEX_END,
|
|
329
|
-
center: this.yoga.ALIGN_CENTER,
|
|
330
|
-
stretch: this.yoga.ALIGN_STRETCH,
|
|
331
|
-
baseline: this.yoga.ALIGN_BASELINE,
|
|
332
|
-
"space-between": this.yoga.ALIGN_SPACE_BETWEEN,
|
|
333
|
-
"space-around": this.yoga.ALIGN_SPACE_AROUND,
|
|
334
|
-
};
|
|
335
|
-
const method = (this.node as any)[methodName].bind(this.node);
|
|
336
|
-
method(mapping[align]);
|
|
283
|
+
this.layout = { flexWrap: wrap };
|
|
337
284
|
}
|
|
338
285
|
|
|
339
286
|
setAlignContent(align: AlignContent) {
|
|
340
|
-
this
|
|
287
|
+
this.layout = { alignContent: align };
|
|
341
288
|
}
|
|
342
289
|
|
|
343
290
|
setAlignSelf(align: AlignContent) {
|
|
344
|
-
this
|
|
291
|
+
this.layout = { alignSelf: align };
|
|
345
292
|
}
|
|
346
293
|
|
|
347
294
|
setAlignItems(align: AlignContent) {
|
|
348
|
-
this
|
|
295
|
+
this.layout = { alignItems: align };
|
|
349
296
|
}
|
|
350
297
|
|
|
351
298
|
setJustifyContent(
|
|
@@ -356,95 +303,133 @@ export function DisplayObject(extendClass) {
|
|
|
356
303
|
| "space-between"
|
|
357
304
|
| "space-around"
|
|
358
305
|
) {
|
|
359
|
-
|
|
360
|
-
"flex-start": this.yoga.JUSTIFY_FLEX_START,
|
|
361
|
-
"flex-end": this.yoga.JUSTIFY_FLEX_END,
|
|
362
|
-
center: this.yoga.JUSTIFY_CENTER,
|
|
363
|
-
"space-between": this.yoga.JUSTIFY_SPACE_BETWEEN,
|
|
364
|
-
"space-around": this.yoga.JUSTIFY_SPACE_AROUND,
|
|
365
|
-
};
|
|
366
|
-
this.node.setJustifyContent(mapping[justifyContent]);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
#setEdgeSize(methodName: string, size: EdgeSize) {
|
|
370
|
-
const method = (this.node as any)[methodName].bind(this.node);
|
|
371
|
-
if (size instanceof Array) {
|
|
372
|
-
if (size.length === 2) {
|
|
373
|
-
method(this.yoga.EDGE_VERTICAL, size[0]);
|
|
374
|
-
method(this.yoga.EDGE_HORIZONTAL, size[1]);
|
|
375
|
-
} else if (size.length === 4) {
|
|
376
|
-
method(this.yoga.EDGE_TOP, size[0]);
|
|
377
|
-
method(this.yoga.EDGE_RIGHT, size[1]);
|
|
378
|
-
method(this.yoga.EDGE_BOTTOM, size[2]);
|
|
379
|
-
method(this.yoga.EDGE_LEFT, size[3]);
|
|
380
|
-
}
|
|
381
|
-
} else {
|
|
382
|
-
method(this.yoga.EDGE_ALL, size);
|
|
383
|
-
}
|
|
306
|
+
this.layout = { justifyContent };
|
|
384
307
|
}
|
|
385
308
|
|
|
386
309
|
setPosition(position: EdgeSize) {
|
|
387
|
-
|
|
310
|
+
if (position instanceof Array) {
|
|
311
|
+
if (position.length === 2) {
|
|
312
|
+
this.layout = {
|
|
313
|
+
positionY: position[0],
|
|
314
|
+
positionX: position[1],
|
|
315
|
+
};
|
|
316
|
+
} else if (position.length === 4) {
|
|
317
|
+
this.layout = {
|
|
318
|
+
positionTop: position[0],
|
|
319
|
+
positionRight: position[1],
|
|
320
|
+
positionBottom: position[2],
|
|
321
|
+
positionLeft: position[3],
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
} else {
|
|
325
|
+
this.layout = { position };
|
|
326
|
+
}
|
|
388
327
|
}
|
|
389
328
|
|
|
390
329
|
setX(x: number) {
|
|
391
330
|
x = x + this.getWidth() * this._anchorPoints.x;
|
|
392
331
|
if (!this.parent.isFlex) {
|
|
393
332
|
this.x = x;
|
|
333
|
+
} else {
|
|
334
|
+
this.x = x;
|
|
335
|
+
this.layout = { x };
|
|
394
336
|
}
|
|
395
|
-
this.node.setPosition(this.yoga.EDGE_LEFT, x);
|
|
396
337
|
}
|
|
397
338
|
|
|
398
339
|
setY(y: number) {
|
|
399
340
|
y = y + this.getHeight() * this._anchorPoints.y;
|
|
400
341
|
if (!this.parent.isFlex) {
|
|
401
342
|
this.y = y;
|
|
343
|
+
} else {
|
|
344
|
+
this.y = y;
|
|
345
|
+
this.layout = { y };
|
|
402
346
|
}
|
|
403
|
-
this.node.setPosition(this.yoga.EDGE_TOP, y);
|
|
404
347
|
}
|
|
405
348
|
|
|
406
349
|
setPadding(padding: EdgeSize) {
|
|
407
|
-
|
|
350
|
+
if (padding instanceof Array) {
|
|
351
|
+
if (padding.length === 2) {
|
|
352
|
+
this.layout = {
|
|
353
|
+
paddingVertical: padding[0],
|
|
354
|
+
paddingHorizontal: padding[1],
|
|
355
|
+
};
|
|
356
|
+
} else if (padding.length === 4) {
|
|
357
|
+
this.layout = {
|
|
358
|
+
paddingTop: padding[0],
|
|
359
|
+
paddingRight: padding[1],
|
|
360
|
+
paddingBottom: padding[2],
|
|
361
|
+
paddingLeft: padding[3],
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
} else {
|
|
365
|
+
this.layout = { padding };
|
|
366
|
+
}
|
|
408
367
|
}
|
|
409
368
|
|
|
410
369
|
setMargin(margin: EdgeSize) {
|
|
411
|
-
|
|
370
|
+
if (margin instanceof Array) {
|
|
371
|
+
if (margin.length === 2) {
|
|
372
|
+
this.layout = {
|
|
373
|
+
marginVertical: margin[0],
|
|
374
|
+
marginHorizontal: margin[1],
|
|
375
|
+
};
|
|
376
|
+
} else if (margin.length === 4) {
|
|
377
|
+
this.layout = {
|
|
378
|
+
marginTop: margin[0],
|
|
379
|
+
marginRight: margin[1],
|
|
380
|
+
marginBottom: margin[2],
|
|
381
|
+
marginLeft: margin[3],
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
} else {
|
|
385
|
+
this.layout = { margin };
|
|
386
|
+
}
|
|
412
387
|
}
|
|
413
388
|
|
|
414
389
|
setGap(gap: EdgeSize) {
|
|
415
|
-
this.
|
|
390
|
+
this.layout = { gap };
|
|
416
391
|
}
|
|
417
392
|
|
|
418
393
|
setBorder(border: EdgeSize) {
|
|
419
|
-
|
|
394
|
+
if (border instanceof Array) {
|
|
395
|
+
if (border.length === 2) {
|
|
396
|
+
this.layout = {
|
|
397
|
+
borderVertical: border[0],
|
|
398
|
+
borderHorizontal: border[1],
|
|
399
|
+
};
|
|
400
|
+
} else if (border.length === 4) {
|
|
401
|
+
this.layout = {
|
|
402
|
+
borderTop: border[0],
|
|
403
|
+
borderRight: border[1],
|
|
404
|
+
borderBottom: border[2],
|
|
405
|
+
borderLeft: border[3],
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
} else {
|
|
409
|
+
this.layout = { border };
|
|
410
|
+
}
|
|
420
411
|
}
|
|
421
412
|
|
|
422
413
|
setPositionType(positionType: "relative" | "absolute") {
|
|
423
|
-
|
|
424
|
-
relative: this.yoga.POSITION_TYPE_RELATIVE,
|
|
425
|
-
absolute: this.yoga.POSITION_TYPE_ABSOLUTE,
|
|
426
|
-
};
|
|
427
|
-
this.node.setPositionType(mapping[positionType]);
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
calculateBounds() {
|
|
431
|
-
super.calculateBounds();
|
|
432
|
-
if (!this._geometry) return;
|
|
433
|
-
const bounds = this._geometry.bounds;
|
|
434
|
-
const width = Math.abs(bounds.minX - bounds.maxX);
|
|
435
|
-
const height = Math.abs(bounds.minY - bounds.maxY);
|
|
436
|
-
// this.node.setWidth(width);
|
|
437
|
-
// this.node.setHeight(height);
|
|
414
|
+
this.layout = { position: positionType };
|
|
438
415
|
}
|
|
439
416
|
|
|
440
417
|
setWidth(width: number) {
|
|
441
418
|
this.displayWidth.set(width);
|
|
442
|
-
this.
|
|
419
|
+
if (!this.parent?.isFlex) {
|
|
420
|
+
this.width = width;
|
|
421
|
+
} else {
|
|
422
|
+
this.layout = { width };
|
|
423
|
+
}
|
|
443
424
|
}
|
|
444
425
|
|
|
445
426
|
setHeight(height: number) {
|
|
446
427
|
this.displayHeight.set(height);
|
|
447
|
-
this.
|
|
428
|
+
if (!this.parent?.isFlex) {
|
|
429
|
+
this.height = height;
|
|
430
|
+
} else {
|
|
431
|
+
this.layout = { height };
|
|
432
|
+
}
|
|
448
433
|
}
|
|
449
434
|
|
|
450
435
|
getWidth() {
|
|
@@ -454,5 +439,79 @@ export function DisplayObject(extendClass) {
|
|
|
454
439
|
getHeight() {
|
|
455
440
|
return this.displayHeight();
|
|
456
441
|
}
|
|
442
|
+
|
|
443
|
+
// Min/Max constraints
|
|
444
|
+
setMinWidth(minWidth: number | string) {
|
|
445
|
+
this.layout = { minWidth };
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
setMinHeight(minHeight: number | string) {
|
|
449
|
+
this.layout = { minHeight };
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
setMaxWidth(maxWidth: number | string) {
|
|
453
|
+
this.layout = { maxWidth };
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
setMaxHeight(maxHeight: number | string) {
|
|
457
|
+
this.layout = { maxHeight };
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Aspect ratio
|
|
461
|
+
setAspectRatio(aspectRatio: number) {
|
|
462
|
+
this.layout = { aspectRatio };
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// Flex properties
|
|
466
|
+
setFlexGrow(flexGrow: number) {
|
|
467
|
+
this.layout = { flexGrow };
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
setFlexShrink(flexShrink: number) {
|
|
471
|
+
this.layout = { flexShrink };
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
setFlexBasis(flexBasis: number | string) {
|
|
475
|
+
this.layout = { flexBasis };
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Gap properties
|
|
479
|
+
setRowGap(rowGap: number) {
|
|
480
|
+
this.layout = { rowGap };
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
setColumnGap(columnGap: number) {
|
|
484
|
+
this.layout = { columnGap };
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Position insets
|
|
488
|
+
setTop(top: number | string) {
|
|
489
|
+
this.layout = { top };
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
setLeft(left: number | string) {
|
|
493
|
+
this.layout = { left };
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
setRight(right: number | string) {
|
|
497
|
+
this.layout = { right };
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
setBottom(bottom: number | string) {
|
|
501
|
+
this.layout = { bottom };
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
// Object properties
|
|
505
|
+
setObjectFit(objectFit: ObjectFit) {
|
|
506
|
+
this.layout = { objectFit };
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
setObjectPosition(objectPosition: ObjectPosition) {
|
|
510
|
+
this.layout = { objectPosition };
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
setTransformOrigin(transformOrigin: TransformOrigin) {
|
|
514
|
+
this.layout = { transformOrigin };
|
|
515
|
+
}
|
|
457
516
|
};
|
|
458
517
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect, effect, Signal } from "@signe/reactive";
|
|
2
2
|
import { Graphics as PixiGraphics } from "pixi.js";
|
|
3
|
-
import { createComponent, registerComponent } from "../engine/reactive";
|
|
4
|
-
import { DisplayObject } from "./DisplayObject";
|
|
3
|
+
import { createComponent, Element, registerComponent } from "../engine/reactive";
|
|
4
|
+
import { ComponentInstance, DisplayObject } from "./DisplayObject";
|
|
5
5
|
import { DisplayObjectProps } from "./types/DisplayObject";
|
|
6
6
|
import { useProps } from "../hooks/useProps";
|
|
7
7
|
import { SignalOrPrimitive } from "./types";
|
|
@@ -44,14 +44,25 @@ class CanvasGraphics extends DisplayObject(PixiGraphics) {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Called when the component is about to be destroyed.
|
|
49
|
+
* This method should be overridden by subclasses to perform any cleanup.
|
|
50
|
+
* It ensures that the clearEffect subscription is unsubscribed before calling the original afterDestroy callback.
|
|
51
|
+
* @param parent The parent element.
|
|
52
|
+
* @param afterDestroy A callback function to be executed after the component's own destruction logic.
|
|
53
|
+
* @example
|
|
54
|
+
* // This method is typically called by the engine internally.
|
|
55
|
+
* // await component.onDestroy(parentElement, () => console.log('Component destroyed'));
|
|
56
|
+
*/
|
|
57
|
+
async onDestroy(parent: Element<ComponentInstance>, afterDestroy: () => void): Promise<void> {
|
|
58
|
+
const _afterDestroyCallback = async () => {
|
|
59
|
+
this.clearEffect.subscription.unsubscribe();
|
|
60
|
+
afterDestroy();
|
|
61
|
+
}
|
|
62
|
+
await super.onDestroy(parent, _afterDestroyCallback);
|
|
50
63
|
}
|
|
51
64
|
}
|
|
52
65
|
|
|
53
|
-
interface CanvasGraphics extends PixiGraphics {}
|
|
54
|
-
|
|
55
66
|
registerComponent("Graphics", CanvasGraphics);
|
|
56
67
|
|
|
57
68
|
export function Graphics(props: GraphicsProps) {
|
|
@@ -2,6 +2,7 @@ import { Assets, NineSliceSprite as PixiNineSliceSprite, Texture } from "pixi.js
|
|
|
2
2
|
import { createComponent, registerComponent } from "../engine/reactive";
|
|
3
3
|
import { DisplayObject } from "./DisplayObject";
|
|
4
4
|
import { DisplayObjectProps } from "./types/DisplayObject";
|
|
5
|
+
import { Layout } from "@pixi/layout";
|
|
5
6
|
|
|
6
7
|
interface NineSliceSpriteProps extends DisplayObjectProps {
|
|
7
8
|
image?: string;
|
|
@@ -37,7 +38,9 @@ class CanvasNineSliceSprite extends DisplayObject(PixiNineSliceSprite) {
|
|
|
37
38
|
}
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
interface CanvasNineSliceSprite extends PixiNineSliceSprite {
|
|
41
|
+
interface CanvasNineSliceSprite extends PixiNineSliceSprite {
|
|
42
|
+
layout: Layout | null;
|
|
43
|
+
}
|
|
41
44
|
|
|
42
45
|
registerComponent("NineSliceSprite", CanvasNineSliceSprite);
|
|
43
46
|
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import * as particles from "@barvynkoa/particle-emitter";
|
|
2
|
-
import { createComponent, registerComponent } from "../engine/reactive";
|
|
2
|
+
import { createComponent, Element, registerComponent } from "../engine/reactive";
|
|
3
3
|
import { CanvasContainer } from "./Container";
|
|
4
4
|
import { Signal } from "@signe/reactive";
|
|
5
|
+
import { ComponentInstance } from "./DisplayObject";
|
|
5
6
|
|
|
6
7
|
class CanvasParticlesEmitter extends CanvasContainer {
|
|
7
8
|
private emitter: particles.Emitter | null;
|
|
8
9
|
private elapsed: number = Date.now();
|
|
9
10
|
|
|
10
|
-
onMount(params) {
|
|
11
|
-
super.onMount(params);
|
|
11
|
+
async onMount(params) {
|
|
12
|
+
await super.onMount(params);
|
|
12
13
|
const { props } = params;
|
|
13
14
|
const tick: Signal = props.context.tick;
|
|
14
15
|
this.emitter = new particles.Emitter(this as any, props.config);
|
|
@@ -24,11 +25,14 @@ class CanvasParticlesEmitter extends CanvasContainer {
|
|
|
24
25
|
|
|
25
26
|
onUpdate(props) {}
|
|
26
27
|
|
|
27
|
-
onDestroy(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
async onDestroy(parent: Element<ComponentInstance>, afterDestroy: () => void) {
|
|
29
|
+
const _afterDestroy = async () => {
|
|
30
|
+
this.emitter?.destroy();
|
|
31
|
+
this.emitter = null;
|
|
32
|
+
this.subscriptionTick.unsubscribe();
|
|
33
|
+
afterDestroy();
|
|
34
|
+
}
|
|
35
|
+
await super.onDestroy(parent, _afterDestroy);
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
38
|
|
package/src/components/Sprite.ts
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
import { ComponentFunction } from "../engine/signal";
|
|
26
26
|
import { DisplayObjectProps } from "./types/DisplayObject";
|
|
27
27
|
import { AnimatedSignal, isAnimatedSignal } from "../engine/animation";
|
|
28
|
+
import { Layout } from '@pixi/layout';
|
|
28
29
|
|
|
29
30
|
const log = console.log;
|
|
30
31
|
|
|
@@ -219,7 +220,7 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
219
220
|
this.sheetCurrentAnimation = StandardAnimation.Stand;
|
|
220
221
|
}
|
|
221
222
|
|
|
222
|
-
this.play(this.sheetCurrentAnimation, [this.sheetParams]);
|
|
223
|
+
if (this.spritesheet) this.play(this.sheetCurrentAnimation, [this.sheetParams]);
|
|
223
224
|
});
|
|
224
225
|
|
|
225
226
|
super.onMount(params);
|
|
@@ -272,8 +273,8 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
272
273
|
}
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
onDestroy(): void {
|
|
276
|
-
super.onDestroy();
|
|
276
|
+
async onDestroy(parent: Element, afterDestroy: () => void): Promise<void> {
|
|
277
|
+
await super.onDestroy(parent);
|
|
277
278
|
this.subscriptionSheet.forEach((sub) => sub.unsubscribe());
|
|
278
279
|
this.subscriptionTick.unsubscribe();
|
|
279
280
|
if (this.currentAnimationContainer && this.parent instanceof Container) {
|
|
@@ -463,7 +464,9 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
463
464
|
}
|
|
464
465
|
}
|
|
465
466
|
|
|
466
|
-
export interface CanvasSprite extends PixiSprite {
|
|
467
|
+
export interface CanvasSprite extends PixiSprite {
|
|
468
|
+
layout: Layout | null;
|
|
469
|
+
}
|
|
467
470
|
|
|
468
471
|
registerComponent("Sprite", CanvasSprite);
|
|
469
472
|
|