canvasengine 2.0.0-beta.6 → 2.0.0-beta.60
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/DebugRenderer-DkjTAc48.js +1384 -0
- package/dist/DebugRenderer-DkjTAc48.js.map +1 -0
- package/dist/components/Button.d.ts +185 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Canvas.d.ts +17 -0
- package/dist/components/Canvas.d.ts.map +1 -0
- package/dist/components/DOMElement.d.ts +54 -0
- package/dist/components/DOMElement.d.ts.map +1 -0
- package/dist/components/DOMSprite.d.ts +127 -0
- package/dist/components/DOMSprite.d.ts.map +1 -0
- package/dist/components/FocusContainer.d.ts +129 -0
- package/dist/components/FocusContainer.d.ts.map +1 -0
- package/dist/components/Graphic.d.ts +64 -0
- package/dist/components/Graphic.d.ts.map +1 -0
- package/dist/components/Joystick.d.ts +36 -0
- package/dist/components/Joystick.d.ts.map +1 -0
- package/dist/components/NineSliceSprite.d.ts +16 -0
- package/dist/components/NineSliceSprite.d.ts.map +1 -0
- package/dist/components/ParticleEmitter.d.ts +4 -0
- package/dist/components/ParticleEmitter.d.ts.map +1 -0
- package/dist/components/Scene.d.ts +2 -0
- package/dist/components/Scene.d.ts.map +1 -0
- package/dist/components/Text.d.ts +25 -0
- package/dist/components/Text.d.ts.map +1 -0
- package/dist/components/TilingSprite.d.ts +17 -0
- package/dist/components/TilingSprite.d.ts.map +1 -0
- package/dist/components/Video.d.ts +14 -0
- package/dist/components/Video.d.ts.map +1 -0
- package/dist/components/index.d.ts +20 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/types/DisplayObject.d.ts +118 -0
- package/dist/components/types/DisplayObject.d.ts.map +1 -0
- package/dist/components/types/MouseEvent.d.ts +4 -0
- package/dist/components/types/MouseEvent.d.ts.map +1 -0
- package/dist/components/types/Spritesheet.d.ts +248 -0
- package/dist/components/types/Spritesheet.d.ts.map +1 -0
- package/dist/components/types/index.d.ts +4 -0
- package/dist/components/types/index.d.ts.map +1 -0
- package/dist/directives/Controls.d.ts +112 -0
- package/dist/directives/Controls.d.ts.map +1 -0
- package/dist/directives/ControlsBase.d.ts +199 -0
- package/dist/directives/ControlsBase.d.ts.map +1 -0
- package/dist/directives/Drag.d.ts +69 -0
- package/dist/directives/Drag.d.ts.map +1 -0
- package/dist/directives/Flash.d.ts +116 -0
- package/dist/directives/Flash.d.ts.map +1 -0
- package/dist/directives/FocusNavigation.d.ts +52 -0
- package/dist/directives/FocusNavigation.d.ts.map +1 -0
- package/dist/directives/FogVisibility.d.ts +47 -0
- package/dist/directives/FogVisibility.d.ts.map +1 -0
- package/dist/directives/GamepadControls.d.ts +224 -0
- package/dist/directives/GamepadControls.d.ts.map +1 -0
- package/dist/directives/JoystickControls.d.ts +171 -0
- package/dist/directives/JoystickControls.d.ts.map +1 -0
- package/dist/directives/KeyboardControls.d.ts +219 -0
- package/dist/directives/KeyboardControls.d.ts.map +1 -0
- package/dist/directives/Scheduler.d.ts +35 -0
- package/dist/directives/Scheduler.d.ts.map +1 -0
- package/dist/directives/Shake.d.ts +98 -0
- package/dist/directives/Shake.d.ts.map +1 -0
- package/dist/directives/Sound.d.ts +25 -0
- package/dist/directives/Sound.d.ts.map +1 -0
- package/dist/directives/Transition.d.ts +10 -0
- package/dist/directives/Transition.d.ts.map +1 -0
- package/dist/directives/ViewportCull.d.ts +11 -0
- package/dist/directives/ViewportCull.d.ts.map +1 -0
- package/dist/directives/ViewportFollow.d.ts +18 -0
- package/dist/directives/ViewportFollow.d.ts.map +1 -0
- package/dist/directives/index.d.ts +14 -0
- package/dist/directives/index.d.ts.map +1 -0
- package/dist/dist-BOOc43Qm.js +778 -0
- package/dist/dist-BOOc43Qm.js.map +1 -0
- package/dist/engine/FocusManager.d.ts +174 -0
- package/dist/engine/FocusManager.d.ts.map +1 -0
- package/dist/engine/animation.d.ts +72 -0
- package/dist/engine/animation.d.ts.map +1 -0
- package/dist/engine/bootstrap.d.ts +48 -0
- package/dist/engine/bootstrap.d.ts.map +1 -0
- package/dist/engine/directive.d.ts +13 -0
- package/dist/engine/directive.d.ts.map +1 -0
- package/dist/engine/reactive.d.ts +134 -0
- package/dist/engine/reactive.d.ts.map +1 -0
- package/dist/engine/signal.d.ts +71 -0
- package/dist/engine/signal.d.ts.map +1 -0
- package/dist/engine/trigger.d.ts +54 -0
- package/dist/engine/trigger.d.ts.map +1 -0
- package/dist/engine/utils.d.ts +89 -0
- package/dist/engine/utils.d.ts.map +1 -0
- package/dist/hooks/addContext.d.ts +2 -0
- package/dist/hooks/addContext.d.ts.map +1 -0
- package/dist/hooks/useFocus.d.ts +60 -0
- package/dist/hooks/useFocus.d.ts.map +1 -0
- package/dist/hooks/useProps.d.ts +42 -0
- package/dist/hooks/useProps.d.ts.map +1 -0
- package/dist/hooks/useRef.d.ts +4 -0
- package/dist/hooks/useRef.d.ts.map +1 -0
- package/dist/index.d.ts +19 -1107
- package/dist/index.d.ts.map +1 -0
- package/dist/index.global.js +5 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +9768 -3135
- package/dist/index.js.map +1 -1
- package/dist/utils/Ease.d.ts +17 -0
- package/dist/utils/Ease.d.ts.map +1 -0
- package/dist/utils/GlobalAssetLoader.d.ts +141 -0
- package/dist/utils/GlobalAssetLoader.d.ts.map +1 -0
- package/dist/utils/RadialGradient.d.ts +57 -0
- package/dist/utils/RadialGradient.d.ts.map +1 -0
- package/dist/utils/functions.d.ts +2 -0
- package/dist/utils/functions.d.ts.map +1 -0
- package/dist/utils/tabindex.d.ts +16 -0
- package/dist/utils/tabindex.d.ts.map +1 -0
- package/package.json +15 -9
- package/src/components/Button.ts +399 -0
- package/src/components/Canvas.ts +62 -46
- package/src/components/Container.ts +21 -2
- package/src/components/DOMContainer.ts +379 -0
- package/src/components/DOMElement.ts +556 -0
- package/src/components/DOMSprite.ts +1040 -0
- package/src/components/DisplayObject.ts +419 -201
- package/src/components/FocusContainer.ts +368 -0
- package/src/components/Graphic.ts +227 -66
- package/src/components/Joystick.ts +363 -0
- package/src/components/Mesh.ts +222 -0
- package/src/components/NineSliceSprite.ts +4 -1
- package/src/components/ParticleEmitter.ts +12 -8
- package/src/components/Sprite.ts +418 -52
- package/src/components/Text.ts +125 -18
- package/src/components/Viewport.ts +122 -63
- package/src/components/index.ts +9 -2
- package/src/components/types/DisplayObject.ts +53 -5
- package/src/components/types/Spritesheet.ts +0 -118
- package/src/directives/Controls.ts +254 -0
- package/src/directives/ControlsBase.ts +267 -0
- package/src/directives/Drag.ts +357 -52
- package/src/directives/Flash.ts +419 -0
- package/src/directives/FocusNavigation.ts +113 -0
- package/src/directives/FogVisibility.ts +273 -0
- package/src/directives/GamepadControls.ts +537 -0
- package/src/directives/JoystickControls.ts +396 -0
- package/src/directives/KeyboardControls.ts +85 -430
- package/src/directives/Scheduler.ts +12 -4
- package/src/directives/Shake.ts +298 -0
- package/src/directives/Sound.ts +94 -31
- package/src/directives/ViewportFollow.ts +40 -9
- package/src/directives/index.ts +13 -6
- package/src/engine/FocusManager.ts +510 -0
- package/src/engine/animation.ts +175 -21
- package/src/engine/bootstrap.ts +93 -3
- package/src/engine/directive.ts +4 -4
- package/src/engine/reactive.ts +979 -176
- package/src/engine/signal.ts +113 -25
- package/src/engine/trigger.ts +34 -7
- package/src/engine/utils.ts +19 -3
- package/src/hooks/useFocus.ts +91 -0
- package/src/hooks/useProps.ts +1 -1
- package/src/index.ts +8 -2
- package/src/types/pixi-cull.d.ts +7 -0
- package/src/utils/GlobalAssetLoader.ts +257 -0
- package/src/utils/functions.ts +7 -0
- package/src/utils/tabindex.ts +70 -0
- package/testing/index.ts +35 -4
- package/tsconfig.json +18 -0
- package/vite.config.ts +39 -0
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Element, isElement, Props } from "../engine/reactive";
|
|
1
|
+
import { Element, isElement, Props, isElementFrozen } 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 {
|
|
12
|
-
import
|
|
11
|
+
import { signal } from "@signe/reactive";
|
|
12
|
+
import { BlurFilter, ObservablePoint, type Point, type Rectangle } from "pixi.js";
|
|
13
|
+
import * as FILTERS from "pixi-filters";
|
|
14
|
+
import { isPercent } from "../utils/functions";
|
|
15
|
+
import { BehaviorSubject, filter, Subject } from "rxjs";
|
|
13
16
|
|
|
14
17
|
export interface ComponentInstance extends PixiMixins.ContainerOptions {
|
|
15
18
|
id?: string;
|
|
16
19
|
children?: ComponentInstance[];
|
|
17
20
|
onInit?(props: Props): void;
|
|
18
21
|
onUpdate?(props: Props): void;
|
|
19
|
-
onDestroy?(parent: Element): void;
|
|
20
|
-
onMount?(context: Element
|
|
22
|
+
onDestroy?(parent: Element, afterDestroy: () => void): void;
|
|
23
|
+
onMount?(context: Element<any>, index?: number): void;
|
|
21
24
|
setWidth(width: number): void;
|
|
22
25
|
setHeight(height: number): void;
|
|
26
|
+
getLocalBounds?(): Rectangle;
|
|
27
|
+
getGlobalPosition?(): Point;
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
export const EVENTS = [
|
|
@@ -93,6 +98,8 @@ export const EVENTS = [
|
|
|
93
98
|
"wheelcapture",
|
|
94
99
|
];
|
|
95
100
|
|
|
101
|
+
export type OnHook = (() => void) | (() => Promise<void> | void);
|
|
102
|
+
|
|
96
103
|
export function DisplayObject(extendClass) {
|
|
97
104
|
return class DisplayObject extends extendClass {
|
|
98
105
|
#canvasContext: {
|
|
@@ -101,117 +108,162 @@ export function DisplayObject(extendClass) {
|
|
|
101
108
|
isFlex: boolean = false;
|
|
102
109
|
fullProps: Props = {};
|
|
103
110
|
isMounted: boolean = false;
|
|
104
|
-
_anchorPoints = new ObservablePoint(
|
|
105
|
-
{ _onUpdate: () => {} },
|
|
106
|
-
0,
|
|
107
|
-
0
|
|
108
|
-
);
|
|
111
|
+
_anchorPoints = new ObservablePoint({ _onUpdate: () => {} }, 0, 0);
|
|
109
112
|
isCustomAnchor: boolean = false;
|
|
110
113
|
displayWidth = signal(0);
|
|
111
114
|
displayHeight = signal(0);
|
|
112
115
|
overrideProps: string[] = [];
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
layout = null;
|
|
117
|
+
onBeforeDestroy: OnHook | null = null;
|
|
118
|
+
onAfterMount: OnHook | null = null;
|
|
119
|
+
subjectInit = new BehaviorSubject(null);
|
|
120
|
+
disableLayout: boolean = false;
|
|
121
|
+
// Store registered event listeners for cleanup
|
|
122
|
+
#registeredEvents: Map<string, Function> = new Map();
|
|
123
|
+
// Store computed layout box dimensions
|
|
124
|
+
#computedLayoutBox: { width?: number; height?: number } | null = null;
|
|
125
|
+
// Store reference to element for freeze checking
|
|
126
|
+
#element: Element<any> | null = null;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Get the element reference for freeze checking
|
|
130
|
+
* @returns The element reference or null
|
|
131
|
+
*/
|
|
132
|
+
getElement(): Element<any> | null {
|
|
133
|
+
return this.#element;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
onLayoutComputed(_event: any) {}
|
|
118
137
|
|
|
119
138
|
get deltaRatio() {
|
|
120
139
|
return this.#canvasContext?.scheduler?.tick.value.deltaRatio;
|
|
121
140
|
}
|
|
122
141
|
|
|
123
|
-
|
|
142
|
+
get parentIsFlex() {
|
|
143
|
+
if (this.disableLayout) return false;
|
|
144
|
+
return this.parent?.isFlex;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
onInit(props: Props) {
|
|
148
|
+
// Ensure layout setter from @pixi/layout is used when available.
|
|
149
|
+
if (Object.prototype.hasOwnProperty.call(this, "layout")) {
|
|
150
|
+
delete (this as any).layout;
|
|
151
|
+
}
|
|
124
152
|
this._id = props.id;
|
|
125
153
|
for (let event of EVENTS) {
|
|
126
154
|
if (props[event] && !this.overrideProps.includes(event)) {
|
|
127
155
|
this.eventMode = "static";
|
|
128
|
-
|
|
156
|
+
const originalEventHandler = props[event];
|
|
157
|
+
|
|
158
|
+
// Wrap event handler to check freeze state
|
|
159
|
+
const wrappedHandler = (...args: any[]) => {
|
|
160
|
+
// Check if element is frozen before executing handler
|
|
161
|
+
if (this.#element && isElementFrozen(this.#element)) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
return originalEventHandler(...args);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// Store the wrapped event handler for cleanup
|
|
168
|
+
if (event === 'click') {
|
|
169
|
+
this.on('pointertap', wrappedHandler);
|
|
170
|
+
this.#registeredEvents.set('pointertap', wrappedHandler);
|
|
171
|
+
} else {
|
|
172
|
+
this.on(event, wrappedHandler);
|
|
173
|
+
this.#registeredEvents.set(event, wrappedHandler);
|
|
174
|
+
}
|
|
129
175
|
}
|
|
130
176
|
}
|
|
177
|
+
if (props.onBeforeDestroy || props['on-before-destroy']) {
|
|
178
|
+
this.onBeforeDestroy = props.onBeforeDestroy || props['on-before-destroy'];
|
|
179
|
+
}
|
|
180
|
+
if (props.onAfterMount || props['on-after-mount']) {
|
|
181
|
+
this.onAfterMount = props.onAfterMount || props['on-after-mount'];
|
|
182
|
+
}
|
|
183
|
+
if (
|
|
184
|
+
props.justifyContent ||
|
|
185
|
+
props.alignItems ||
|
|
186
|
+
props.flexDirection ||
|
|
187
|
+
props.flexWrap ||
|
|
188
|
+
props.alignContent ||
|
|
189
|
+
props.display == "flex" ||
|
|
190
|
+
isPercent(props.width) ||
|
|
191
|
+
isPercent(props.height) ||
|
|
192
|
+
props.isRoot
|
|
193
|
+
) {
|
|
194
|
+
this.layout = {};
|
|
195
|
+
this.isFlex = true;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
this.subjectInit.next(this);
|
|
131
199
|
}
|
|
132
200
|
|
|
133
|
-
onMount(
|
|
134
|
-
this
|
|
135
|
-
this
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
201
|
+
async onMount(element: Element<any>, index?: number) {
|
|
202
|
+
if (this.destroyed) return
|
|
203
|
+
this.#element = element;
|
|
204
|
+
this.#canvasContext = element.props.context;
|
|
205
|
+
if (element.parent) {
|
|
206
|
+
let parentElement = element.parent;
|
|
207
|
+
let instance = parentElement.componentInstance as DisplayObject;
|
|
208
|
+
if (typeof (instance as any)?.addChild !== "function") {
|
|
209
|
+
let search = parentElement.parent;
|
|
210
|
+
while (search && typeof (search.componentInstance as any)?.addChild !== "function") {
|
|
211
|
+
search = search.parent;
|
|
212
|
+
}
|
|
213
|
+
if (search && typeof (search.componentInstance as any)?.addChild === "function") {
|
|
214
|
+
parentElement = search;
|
|
215
|
+
instance = parentElement.componentInstance as DisplayObject;
|
|
216
|
+
} else {
|
|
217
|
+
console.warn("DisplayObject mount skipped: parent has no addChild", {
|
|
218
|
+
child: element.tag,
|
|
219
|
+
parent: element.parent?.tag,
|
|
220
|
+
});
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (instance.isFlex && !this.layout && !this.disableLayout) {
|
|
225
|
+
try {
|
|
226
|
+
this.layout = {};
|
|
227
|
+
} catch (error) {
|
|
228
|
+
console.warn('Failed to set layout:', error);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
if (index === undefined || parentElement !== element.parent || typeof (instance as any)?.addChildAt !== "function") {
|
|
139
232
|
instance.addChild(this);
|
|
140
233
|
} else {
|
|
141
234
|
instance.addChildAt(this, index);
|
|
142
235
|
}
|
|
143
|
-
if (instance.layer) this.parentLayer = instance.layer;
|
|
144
236
|
this.isMounted = true;
|
|
145
|
-
this.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const { left, top } = child.getComputedLayout();
|
|
155
|
-
child.x = left;
|
|
156
|
-
child.y = top;
|
|
237
|
+
this.onUpdate(element.props);
|
|
238
|
+
|
|
239
|
+
// Listen to layout events to store computed layout dimensions
|
|
240
|
+
const layoutHandler = (event: any) => {
|
|
241
|
+
if (event.computedLayout) {
|
|
242
|
+
this.#computedLayoutBox = {
|
|
243
|
+
width: event.computedLayout.width,
|
|
244
|
+
height: event.computedLayout.height,
|
|
245
|
+
};
|
|
157
246
|
}
|
|
247
|
+
this.onLayoutComputed(event);
|
|
248
|
+
};
|
|
249
|
+
this.on('layout', layoutHandler);
|
|
250
|
+
this.#registeredEvents.set('layout', layoutHandler);
|
|
251
|
+
|
|
252
|
+
if (this.onAfterMount) {
|
|
253
|
+
await this.onAfterMount();
|
|
158
254
|
}
|
|
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);
|
|
178
|
-
}
|
|
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
255
|
}
|
|
206
256
|
}
|
|
207
257
|
|
|
208
|
-
onUpdate(props) {
|
|
258
|
+
onUpdate(props: Props) {
|
|
209
259
|
this.fullProps = {
|
|
210
260
|
...this.fullProps,
|
|
211
261
|
...props,
|
|
212
262
|
};
|
|
213
263
|
|
|
264
|
+
if (this.destroyed) return
|
|
214
265
|
if (!this.#canvasContext || !this.parent) return;
|
|
266
|
+
|
|
215
267
|
if (props.x !== undefined) this.setX(props.x);
|
|
216
268
|
if (props.y !== undefined) this.setY(props.y);
|
|
217
269
|
if (props.scale !== undefined)
|
|
@@ -219,6 +271,28 @@ export function DisplayObject(extendClass) {
|
|
|
219
271
|
if (props.anchor !== undefined && !this.isCustomAnchor) {
|
|
220
272
|
setObservablePoint(this.anchor, props.anchor);
|
|
221
273
|
}
|
|
274
|
+
if (props.width !== undefined) this.setWidth(props.width);
|
|
275
|
+
if (props.height !== undefined) this.setHeight(props.height);
|
|
276
|
+
if (props.minWidth !== undefined) this.setMinWidth(props.minWidth);
|
|
277
|
+
if (props.minHeight !== undefined) this.setMinHeight(props.minHeight);
|
|
278
|
+
if (props.maxWidth !== undefined) this.setMaxWidth(props.maxWidth);
|
|
279
|
+
if (props.maxHeight !== undefined) this.setMaxHeight(props.maxHeight);
|
|
280
|
+
if (props.aspectRatio !== undefined)
|
|
281
|
+
this.setAspectRatio(props.aspectRatio);
|
|
282
|
+
if (props.flexGrow !== undefined) this.setFlexGrow(props.flexGrow);
|
|
283
|
+
if (props.flexShrink !== undefined) this.setFlexShrink(props.flexShrink);
|
|
284
|
+
if (props.flexBasis !== undefined) this.setFlexBasis(props.flexBasis);
|
|
285
|
+
if (props.rowGap !== undefined) this.setRowGap(props.rowGap);
|
|
286
|
+
if (props.columnGap !== undefined) this.setColumnGap(props.columnGap);
|
|
287
|
+
if (props.top !== undefined) this.setTop(props.top);
|
|
288
|
+
if (props.left !== undefined) this.setLeft(props.left);
|
|
289
|
+
if (props.right !== undefined) this.setRight(props.right);
|
|
290
|
+
if (props.bottom !== undefined) this.setBottom(props.bottom);
|
|
291
|
+
if (props.objectFit !== undefined) this.setObjectFit(props.objectFit);
|
|
292
|
+
if (props.objectPosition !== undefined)
|
|
293
|
+
this.setObjectPosition(props.objectPosition);
|
|
294
|
+
if (props.transformOrigin !== undefined)
|
|
295
|
+
this.setTransformOrigin(props.transformOrigin);
|
|
222
296
|
if (props.skew !== undefined) setObservablePoint(this.skew, props.skew);
|
|
223
297
|
if (props.tint) this.tint = props.tint;
|
|
224
298
|
if (props.rotation !== undefined) this.rotation = props.rotation;
|
|
@@ -243,23 +317,51 @@ export function DisplayObject(extendClass) {
|
|
|
243
317
|
if (props.filters) this.filters = props.filters;
|
|
244
318
|
if (props.maskOf) {
|
|
245
319
|
if (isElement(props.maskOf)) {
|
|
246
|
-
props.maskOf.componentInstance.mask = this;
|
|
320
|
+
props.maskOf.componentInstance.mask = this as any;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
if (props.shadowCaster !== undefined) {
|
|
324
|
+
const shadowCasterValue = (props.shadowCaster as any)?.value ?? props.shadowCaster;
|
|
325
|
+
if (
|
|
326
|
+
shadowCasterValue &&
|
|
327
|
+
typeof shadowCasterValue === "object" &&
|
|
328
|
+
!Array.isArray(shadowCasterValue)
|
|
329
|
+
) {
|
|
330
|
+
const current = ((this as any).shadowCaster ?? {}) as Record<string, unknown>;
|
|
331
|
+
(this as any).shadowCaster = { ...current, ...shadowCasterValue };
|
|
332
|
+
} else {
|
|
333
|
+
(this as any).shadowCaster = shadowCasterValue;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (props.footprintCaster !== undefined) {
|
|
337
|
+
const footprintCasterValue =
|
|
338
|
+
(props.footprintCaster as any)?.value ?? props.footprintCaster;
|
|
339
|
+
if (
|
|
340
|
+
footprintCasterValue &&
|
|
341
|
+
typeof footprintCasterValue === "object" &&
|
|
342
|
+
!Array.isArray(footprintCasterValue)
|
|
343
|
+
) {
|
|
344
|
+
const current = ((this as any).footprintCaster ?? {}) as Record<string, unknown>;
|
|
345
|
+
(this as any).footprintCaster = { ...current, ...footprintCasterValue };
|
|
346
|
+
} else {
|
|
347
|
+
(this as any).footprintCaster = footprintCasterValue;
|
|
247
348
|
}
|
|
248
349
|
}
|
|
249
350
|
if (props.blendMode) this.blendMode = props.blendMode;
|
|
250
351
|
if (props.filterArea) this.filterArea = props.filterArea;
|
|
251
352
|
const currentFilters = this.filters || [];
|
|
252
353
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
354
|
+
// TODO: Fix DropShadowFilter import issue
|
|
355
|
+
// if (props.shadow) {
|
|
356
|
+
// let dropShadowFilter = currentFilters.find(
|
|
357
|
+
// (filter) => filter instanceof FILTERS.DropShadowFilter
|
|
358
|
+
// );
|
|
359
|
+
// if (!dropShadowFilter) {
|
|
360
|
+
// dropShadowFilter = new FILTERS.DropShadowFilter();
|
|
361
|
+
// currentFilters.push(dropShadowFilter);
|
|
362
|
+
// }
|
|
363
|
+
// Object.assign(dropShadowFilter, props.shadow);
|
|
364
|
+
// }
|
|
263
365
|
|
|
264
366
|
if (props.blur) {
|
|
265
367
|
let blurFilter = currentFilters.find(
|
|
@@ -279,73 +381,41 @@ export function DisplayObject(extendClass) {
|
|
|
279
381
|
}
|
|
280
382
|
|
|
281
383
|
this.filters = currentFilters;
|
|
282
|
-
|
|
283
|
-
this.#flexRender(props);
|
|
284
384
|
}
|
|
285
385
|
|
|
286
|
-
onDestroy() {
|
|
287
|
-
|
|
288
|
-
this
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
applyComputedLayout() {
|
|
296
|
-
const layout = this.getComputedLayout();
|
|
297
|
-
this.x = layout.left;
|
|
298
|
-
this.y = layout.top;
|
|
299
|
-
}
|
|
386
|
+
async onDestroy(parent: Element, afterDestroy?: () => void) {
|
|
387
|
+
// Remove all registered event listeners
|
|
388
|
+
for (const [eventName, eventHandler] of this.#registeredEvents) {
|
|
389
|
+
this.off(eventName, eventHandler);
|
|
390
|
+
}
|
|
391
|
+
this.#registeredEvents.clear();
|
|
392
|
+
this.#element = null;
|
|
300
393
|
|
|
301
|
-
|
|
302
|
-
|
|
394
|
+
if (this.onBeforeDestroy) {
|
|
395
|
+
await this.onBeforeDestroy();
|
|
396
|
+
}
|
|
397
|
+
if (afterDestroy) afterDestroy();
|
|
398
|
+
super.destroy();
|
|
303
399
|
}
|
|
304
400
|
|
|
305
401
|
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]);
|
|
402
|
+
this.layout = { flexDirection: direction };
|
|
313
403
|
}
|
|
314
404
|
|
|
315
405
|
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]);
|
|
406
|
+
this.layout = { flexWrap: wrap };
|
|
337
407
|
}
|
|
338
408
|
|
|
339
409
|
setAlignContent(align: AlignContent) {
|
|
340
|
-
this
|
|
410
|
+
this.layout = { alignContent: align };
|
|
341
411
|
}
|
|
342
412
|
|
|
343
413
|
setAlignSelf(align: AlignContent) {
|
|
344
|
-
this
|
|
414
|
+
this.layout = { alignSelf: align };
|
|
345
415
|
}
|
|
346
416
|
|
|
347
417
|
setAlignItems(align: AlignContent) {
|
|
348
|
-
this
|
|
418
|
+
this.layout = { alignItems: align };
|
|
349
419
|
}
|
|
350
420
|
|
|
351
421
|
setJustifyContent(
|
|
@@ -356,103 +426,251 @@ export function DisplayObject(extendClass) {
|
|
|
356
426
|
| "space-between"
|
|
357
427
|
| "space-around"
|
|
358
428
|
) {
|
|
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
|
-
}
|
|
429
|
+
this.layout = { justifyContent };
|
|
384
430
|
}
|
|
385
431
|
|
|
386
432
|
setPosition(position: EdgeSize) {
|
|
387
|
-
|
|
433
|
+
if (position instanceof Array) {
|
|
434
|
+
if (position.length === 2) {
|
|
435
|
+
this.layout = {
|
|
436
|
+
positionY: position[0],
|
|
437
|
+
positionX: position[1],
|
|
438
|
+
};
|
|
439
|
+
} else if (position.length === 4) {
|
|
440
|
+
this.layout = {
|
|
441
|
+
positionTop: position[0],
|
|
442
|
+
positionRight: position[1],
|
|
443
|
+
positionBottom: position[2],
|
|
444
|
+
positionLeft: position[3],
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
} else {
|
|
448
|
+
this.layout = { position };
|
|
449
|
+
}
|
|
388
450
|
}
|
|
389
451
|
|
|
390
452
|
setX(x: number) {
|
|
391
453
|
x = x + this.getWidth() * this._anchorPoints.x;
|
|
392
|
-
if (!this.
|
|
454
|
+
if (!this.parentIsFlex) {
|
|
455
|
+
this.x = x;
|
|
456
|
+
} else {
|
|
393
457
|
this.x = x;
|
|
458
|
+
this.layout = { x };
|
|
394
459
|
}
|
|
395
|
-
this.node.setPosition(this.yoga.EDGE_LEFT, x);
|
|
396
460
|
}
|
|
397
461
|
|
|
398
462
|
setY(y: number) {
|
|
399
463
|
y = y + this.getHeight() * this._anchorPoints.y;
|
|
400
|
-
if (!this.
|
|
464
|
+
if (!this.parentIsFlex) {
|
|
401
465
|
this.y = y;
|
|
466
|
+
} else {
|
|
467
|
+
this.y = y;
|
|
468
|
+
this.layout = { y };
|
|
402
469
|
}
|
|
403
|
-
this.node.setPosition(this.yoga.EDGE_TOP, y);
|
|
404
470
|
}
|
|
405
471
|
|
|
406
472
|
setPadding(padding: EdgeSize) {
|
|
407
|
-
|
|
473
|
+
if (padding instanceof Array) {
|
|
474
|
+
if (padding.length === 2) {
|
|
475
|
+
this.layout = {
|
|
476
|
+
paddingVertical: padding[0],
|
|
477
|
+
paddingHorizontal: padding[1],
|
|
478
|
+
};
|
|
479
|
+
} else if (padding.length === 4) {
|
|
480
|
+
this.layout = {
|
|
481
|
+
paddingTop: padding[0],
|
|
482
|
+
paddingRight: padding[1],
|
|
483
|
+
paddingBottom: padding[2],
|
|
484
|
+
paddingLeft: padding[3],
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
this.layout = { padding };
|
|
489
|
+
}
|
|
408
490
|
}
|
|
409
491
|
|
|
410
492
|
setMargin(margin: EdgeSize) {
|
|
411
|
-
|
|
493
|
+
if (margin instanceof Array) {
|
|
494
|
+
if (margin.length === 2) {
|
|
495
|
+
this.layout = {
|
|
496
|
+
marginVertical: margin[0],
|
|
497
|
+
marginHorizontal: margin[1],
|
|
498
|
+
};
|
|
499
|
+
} else if (margin.length === 4) {
|
|
500
|
+
this.layout = {
|
|
501
|
+
marginTop: margin[0],
|
|
502
|
+
marginRight: margin[1],
|
|
503
|
+
marginBottom: margin[2],
|
|
504
|
+
marginLeft: margin[3],
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
} else {
|
|
508
|
+
this.layout = { margin };
|
|
509
|
+
}
|
|
412
510
|
}
|
|
413
511
|
|
|
414
512
|
setGap(gap: EdgeSize) {
|
|
415
|
-
this.
|
|
513
|
+
this.layout = { gap };
|
|
416
514
|
}
|
|
417
515
|
|
|
418
516
|
setBorder(border: EdgeSize) {
|
|
419
|
-
|
|
517
|
+
if (border instanceof Array) {
|
|
518
|
+
if (border.length === 2) {
|
|
519
|
+
this.layout = {
|
|
520
|
+
borderVertical: border[0],
|
|
521
|
+
borderHorizontal: border[1],
|
|
522
|
+
};
|
|
523
|
+
} else if (border.length === 4) {
|
|
524
|
+
this.layout = {
|
|
525
|
+
borderTop: border[0],
|
|
526
|
+
borderRight: border[1],
|
|
527
|
+
borderBottom: border[2],
|
|
528
|
+
borderLeft: border[3],
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
} else {
|
|
532
|
+
this.layout = { border };
|
|
533
|
+
}
|
|
420
534
|
}
|
|
421
535
|
|
|
422
536
|
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);
|
|
537
|
+
this.layout = { position: positionType };
|
|
438
538
|
}
|
|
439
539
|
|
|
440
540
|
setWidth(width: number) {
|
|
441
541
|
this.displayWidth.set(width);
|
|
442
|
-
this.
|
|
542
|
+
if (!this.parentIsFlex) {
|
|
543
|
+
this.width = width;
|
|
544
|
+
} else {
|
|
545
|
+
this.layout = { width };
|
|
546
|
+
}
|
|
443
547
|
}
|
|
444
548
|
|
|
445
549
|
setHeight(height: number) {
|
|
446
550
|
this.displayHeight.set(height);
|
|
447
|
-
this.
|
|
551
|
+
if (!this.parentIsFlex) {
|
|
552
|
+
this.height = height;
|
|
553
|
+
} else {
|
|
554
|
+
this.layout = { height };
|
|
555
|
+
}
|
|
448
556
|
}
|
|
449
557
|
|
|
450
|
-
getWidth() {
|
|
451
|
-
|
|
558
|
+
getWidth(): number {
|
|
559
|
+
// If width is a percentage, use computed layout box
|
|
560
|
+
if (isPercent(this.fullProps.width)) {
|
|
561
|
+
if (this.#computedLayoutBox?.width !== undefined) {
|
|
562
|
+
return this.#computedLayoutBox.width;
|
|
563
|
+
}
|
|
564
|
+
// Fallback to native width if layout not yet computed
|
|
565
|
+
return typeof this.width === 'number' ? this.width : 0;
|
|
566
|
+
}
|
|
567
|
+
// For static values, use native PixiJS width or displayWidth signal
|
|
568
|
+
const staticWidth = typeof this.width === 'number' && this.width > 0
|
|
569
|
+
? this.width
|
|
570
|
+
: (typeof this.displayWidth() === 'number' ? this.displayWidth() : 0);
|
|
571
|
+
return staticWidth;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
getHeight(): number {
|
|
575
|
+
// If height is a percentage, use computed layout box
|
|
576
|
+
if (isPercent(this.fullProps.height)) {
|
|
577
|
+
if (this.#computedLayoutBox?.height !== undefined) {
|
|
578
|
+
return this.#computedLayoutBox.height;
|
|
579
|
+
}
|
|
580
|
+
// Fallback to native height if layout not yet computed
|
|
581
|
+
return typeof this.height === 'number' ? this.height : 0;
|
|
582
|
+
}
|
|
583
|
+
// For static values, use native PixiJS height or displayHeight signal
|
|
584
|
+
const staticHeight = typeof this.height === 'number' && this.height > 0
|
|
585
|
+
? this.height
|
|
586
|
+
: (typeof this.displayHeight() === 'number' ? this.displayHeight() : 0);
|
|
587
|
+
return staticHeight;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Min/Max constraints
|
|
591
|
+
setMinWidth(minWidth: number | string) {
|
|
592
|
+
this.layout = { minWidth };
|
|
452
593
|
}
|
|
453
594
|
|
|
454
|
-
|
|
455
|
-
|
|
595
|
+
setMinHeight(minHeight: number | string) {
|
|
596
|
+
this.layout = { minHeight };
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
setMaxWidth(maxWidth: number | string) {
|
|
600
|
+
this.layout = { maxWidth };
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
setMaxHeight(maxHeight: number | string) {
|
|
604
|
+
this.layout = { maxHeight };
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Aspect ratio
|
|
608
|
+
setAspectRatio(aspectRatio: number) {
|
|
609
|
+
this.layout = { aspectRatio };
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// Flex properties
|
|
613
|
+
setFlexGrow(flexGrow: number) {
|
|
614
|
+
this.layout = { flexGrow };
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
setFlexShrink(flexShrink: number) {
|
|
618
|
+
this.layout = { flexShrink };
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
setFlexBasis(flexBasis: number | string) {
|
|
622
|
+
this.layout = { flexBasis };
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Gap properties
|
|
626
|
+
setRowGap(rowGap: number) {
|
|
627
|
+
this.layout = { rowGap };
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
setColumnGap(columnGap: number) {
|
|
631
|
+
this.layout = { columnGap };
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// Position insets
|
|
635
|
+
setTop(top: number | string) {
|
|
636
|
+
this.layout = { top };
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
setLeft(left: number | string) {
|
|
640
|
+
this.layout = { left };
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
setRight(right: number | string) {
|
|
644
|
+
this.layout = { right };
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
setBottom(bottom: number | string) {
|
|
648
|
+
this.layout = { bottom };
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Object properties
|
|
652
|
+
setObjectFit(objectFit: ObjectFit) {
|
|
653
|
+
try {
|
|
654
|
+
this.layout = { objectFit };
|
|
655
|
+
} catch (error) {
|
|
656
|
+
// Ignore layout errors in test environments or when yoga-layout is not available
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
setObjectPosition(objectPosition: ObjectPosition) {
|
|
661
|
+
try {
|
|
662
|
+
this.layout = { objectPosition };
|
|
663
|
+
} catch (error) {
|
|
664
|
+
// Ignore layout errors in test environments or when yoga-layout is not available
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
setTransformOrigin(transformOrigin: TransformOrigin) {
|
|
669
|
+
try {
|
|
670
|
+
this.layout = { transformOrigin };
|
|
671
|
+
} catch (error) {
|
|
672
|
+
// Ignore layout errors in test environments or when yoga-layout is not available
|
|
673
|
+
}
|
|
456
674
|
}
|
|
457
675
|
};
|
|
458
676
|
}
|