canvasengine 2.0.0-beta.3 → 2.0.0-beta.30
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-DcvJLrrD.js +172 -0
- package/dist/DebugRenderer-DcvJLrrD.js.map +1 -0
- package/dist/components/Button.d.ts +136 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Canvas.d.ts +18 -0
- package/dist/components/Canvas.d.ts.map +1 -0
- package/dist/components/Container.d.ts +80 -0
- package/dist/components/Container.d.ts.map +1 -0
- package/dist/components/DOMContainer.d.ts +77 -0
- package/dist/components/DOMContainer.d.ts.map +1 -0
- package/dist/components/DOMElement.d.ts +44 -0
- package/dist/components/DOMElement.d.ts.map +1 -0
- package/dist/components/DisplayObject.d.ts +82 -0
- package/dist/components/DisplayObject.d.ts.map +1 -0
- package/dist/components/Graphic.d.ts +65 -0
- package/dist/components/Graphic.d.ts.map +1 -0
- package/dist/components/Mesh.d.ts +202 -0
- package/dist/components/Mesh.d.ts.map +1 -0
- package/dist/components/NineSliceSprite.d.ts +17 -0
- package/dist/components/NineSliceSprite.d.ts.map +1 -0
- package/dist/components/ParticleEmitter.d.ts +5 -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/Sprite.d.ts +174 -0
- package/dist/components/Sprite.d.ts.map +1 -0
- package/dist/components/Text.d.ts +21 -0
- package/dist/components/Text.d.ts.map +1 -0
- package/dist/components/TilingSprite.d.ts +18 -0
- package/dist/components/TilingSprite.d.ts.map +1 -0
- package/dist/components/Video.d.ts +15 -0
- package/dist/components/Video.d.ts.map +1 -0
- package/dist/components/Viewport.d.ts +106 -0
- package/dist/components/Viewport.d.ts.map +1 -0
- package/dist/components/index.d.ts +17 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/types/DisplayObject.d.ts +106 -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 +366 -0
- package/dist/components/types/Spritesheet.d.ts.map +1 -0
- package/dist/components/types/index.d.ts +5 -0
- package/dist/components/types/index.d.ts.map +1 -0
- package/dist/directives/Drag.d.ts +70 -0
- package/dist/directives/Drag.d.ts.map +1 -0
- package/dist/directives/KeyboardControls.d.ts +530 -0
- package/dist/directives/KeyboardControls.d.ts.map +1 -0
- package/dist/directives/Scheduler.d.ts +36 -0
- package/dist/directives/Scheduler.d.ts.map +1 -0
- package/dist/directives/Sound.d.ts +26 -0
- package/dist/directives/Sound.d.ts.map +1 -0
- package/dist/directives/Transition.d.ts +11 -0
- package/dist/directives/Transition.d.ts.map +1 -0
- package/dist/directives/ViewportCull.d.ts +12 -0
- package/dist/directives/ViewportCull.d.ts.map +1 -0
- package/dist/directives/ViewportFollow.d.ts +19 -0
- package/dist/directives/ViewportFollow.d.ts.map +1 -0
- package/dist/directives/index.d.ts +2 -0
- package/dist/directives/index.d.ts.map +1 -0
- package/dist/engine/animation.d.ts +59 -0
- package/dist/engine/animation.d.ts.map +1 -0
- package/dist/engine/bootstrap.d.ts +16 -0
- package/dist/engine/bootstrap.d.ts.map +1 -0
- package/dist/engine/directive.d.ts +14 -0
- package/dist/engine/directive.d.ts.map +1 -0
- package/dist/engine/reactive.d.ts +95 -0
- package/dist/engine/reactive.d.ts.map +1 -0
- package/dist/engine/signal.d.ts +72 -0
- package/dist/engine/signal.d.ts.map +1 -0
- package/dist/engine/trigger.d.ts +51 -0
- package/dist/engine/trigger.d.ts.map +1 -0
- package/dist/engine/utils.d.ts +90 -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/useProps.d.ts +42 -0
- package/dist/hooks/useProps.d.ts.map +1 -0
- package/dist/hooks/useRef.d.ts +5 -0
- package/dist/hooks/useRef.d.ts.map +1 -0
- package/dist/index-C-iY-lCt.js +11080 -0
- package/dist/index-C-iY-lCt.js.map +1 -0
- package/dist/index.d.ts +15 -919
- package/dist/index.d.ts.map +1 -0
- package/dist/index.global.js +29 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +63 -2950
- 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/RadialGradient.d.ts +58 -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/index.d.ts +4 -0
- package/package.json +12 -7
- package/src/components/Button.ts +269 -0
- package/src/components/Canvas.ts +53 -45
- package/src/components/Container.ts +2 -2
- package/src/components/DOMContainer.ts +123 -0
- package/src/components/DOMElement.ts +421 -0
- package/src/components/DisplayObject.ts +283 -190
- package/src/components/Graphic.ts +200 -34
- 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 +92 -22
- package/src/components/Text.ts +34 -14
- package/src/components/Video.ts +110 -0
- package/src/components/Viewport.ts +59 -43
- package/src/components/index.ts +7 -2
- package/src/components/types/DisplayObject.ts +30 -0
- package/src/directives/Drag.ts +357 -52
- package/src/directives/KeyboardControls.ts +3 -1
- package/src/directives/Sound.ts +94 -31
- package/src/directives/ViewportFollow.ts +35 -7
- package/src/engine/animation.ts +41 -5
- package/src/engine/bootstrap.ts +23 -3
- package/src/engine/directive.ts +2 -2
- package/src/engine/reactive.ts +472 -172
- package/src/engine/signal.ts +18 -2
- package/src/engine/trigger.ts +65 -9
- package/src/engine/utils.ts +97 -9
- package/src/hooks/useProps.ts +1 -1
- package/src/index.ts +4 -1
- package/src/utils/RadialGradient.ts +29 -0
- package/src/utils/functions.ts +7 -0
- package/testing/index.ts +12 -0
- package/tsconfig.json +17 -0
- package/vite.config.ts +39 -0
package/src/components/Sprite.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Howl } from 'howler';
|
|
2
|
+
import { computed, effect, isSignal, Signal } from "@signe/reactive";
|
|
2
3
|
import {
|
|
4
|
+
Application,
|
|
3
5
|
Assets,
|
|
4
6
|
Container,
|
|
5
7
|
Sprite as PixiSprite,
|
|
@@ -10,6 +12,7 @@ import { Subscription } from "rxjs";
|
|
|
10
12
|
import {
|
|
11
13
|
Element,
|
|
12
14
|
createComponent,
|
|
15
|
+
isElement,
|
|
13
16
|
registerComponent,
|
|
14
17
|
} from "../engine/reactive";
|
|
15
18
|
import { arrayEquals, isFunction } from "../engine/utils";
|
|
@@ -24,6 +27,7 @@ import {
|
|
|
24
27
|
import { ComponentFunction } from "../engine/signal";
|
|
25
28
|
import { DisplayObjectProps } from "./types/DisplayObject";
|
|
26
29
|
import { AnimatedSignal, isAnimatedSignal } from "../engine/animation";
|
|
30
|
+
import { Layout } from '@pixi/layout';
|
|
27
31
|
|
|
28
32
|
const log = console.log;
|
|
29
33
|
|
|
@@ -73,14 +77,25 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
73
77
|
private subscriptionSheet: Subscription[] = [];
|
|
74
78
|
private sheetParams: any = {};
|
|
75
79
|
private sheetCurrentAnimation: string = StandardAnimation.Stand;
|
|
80
|
+
private app: Application | null = null;
|
|
76
81
|
onFinish: () => void;
|
|
77
82
|
|
|
83
|
+
get renderer() {
|
|
84
|
+
return this.app?.renderer;
|
|
85
|
+
}
|
|
86
|
+
|
|
78
87
|
private currentAnimationContainer: Container | null = null;
|
|
79
88
|
|
|
80
89
|
private async createTextures(
|
|
81
90
|
options: Required<TextureOptionsMerging>
|
|
82
91
|
): Promise<Texture[][]> {
|
|
83
92
|
const { width, height, framesHeight, framesWidth, image, offset } = options;
|
|
93
|
+
|
|
94
|
+
if (!image || typeof image !== 'string' || image.trim() === '') {
|
|
95
|
+
console.warn('Invalid image path provided to createTextures:', image);
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
|
|
84
99
|
const texture = await Assets.load(image);
|
|
85
100
|
const spriteWidth = options.spriteWidth;
|
|
86
101
|
const spriteHeight = options.spriteHeight;
|
|
@@ -167,10 +182,12 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
167
182
|
const { props, propObservables } = params;
|
|
168
183
|
const tick: Signal = props.context.tick;
|
|
169
184
|
const sheet = props.sheet ?? {};
|
|
185
|
+
this.app = props.context.app();
|
|
170
186
|
if (sheet?.onFinish) {
|
|
171
187
|
this.onFinish = sheet.onFinish;
|
|
172
188
|
}
|
|
173
189
|
this.subscriptionTick = tick.observable.subscribe((value) => {
|
|
190
|
+
if (this.destroyed) return
|
|
174
191
|
this.update(value);
|
|
175
192
|
});
|
|
176
193
|
if (props.sheet?.definition) {
|
|
@@ -218,15 +235,38 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
218
235
|
this.sheetCurrentAnimation = StandardAnimation.Stand;
|
|
219
236
|
}
|
|
220
237
|
|
|
221
|
-
this.play(this.sheetCurrentAnimation, [this.sheetParams]);
|
|
238
|
+
if (this.spritesheet) this.play(this.sheetCurrentAnimation, [this.sheetParams]);
|
|
222
239
|
});
|
|
223
|
-
|
|
224
240
|
super.onMount(params);
|
|
225
241
|
}
|
|
226
242
|
|
|
227
243
|
async onUpdate(props) {
|
|
244
|
+
if (this.destroyed) return
|
|
228
245
|
super.onUpdate(props);
|
|
229
246
|
|
|
247
|
+
const setTexture = async (image: string) => {
|
|
248
|
+
if (!image || typeof image !== 'string' || image.trim() === '') {
|
|
249
|
+
console.warn('Invalid image path provided to setTexture:', image);
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const onProgress = this.fullProps.loader?.onProgress;
|
|
254
|
+
const texture = await Assets.load(image, (progress) => {
|
|
255
|
+
if (onProgress) onProgress(progress);
|
|
256
|
+
if (progress == 1) {
|
|
257
|
+
const onComplete = this.fullProps.loader?.onComplete;
|
|
258
|
+
if (onComplete) {
|
|
259
|
+
// hack to memoize the texture
|
|
260
|
+
setTimeout(() => {
|
|
261
|
+
onComplete(texture);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
return texture
|
|
268
|
+
}
|
|
269
|
+
|
|
230
270
|
const sheet = props.sheet;
|
|
231
271
|
if (sheet?.params) this.sheetParams = sheet?.params;
|
|
232
272
|
|
|
@@ -235,32 +275,50 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
235
275
|
this.play(this.sheetCurrentAnimation, [this.sheetParams]);
|
|
236
276
|
}
|
|
237
277
|
|
|
238
|
-
if (props.hitbox) this.hitbox = props.hitbox;
|
|
278
|
+
if (props.hitbox) this.hitbox = props.hitbox.value ?? props.hitbox;
|
|
239
279
|
|
|
240
280
|
if (props.scaleMode) this.baseTexture.scaleMode = props.scaleMode;
|
|
241
281
|
else if (props.image && this.fullProps.rectangle === undefined) {
|
|
242
|
-
|
|
282
|
+
const texture = await setTexture(this.fullProps.image);
|
|
283
|
+
if (texture) {
|
|
284
|
+
this.texture = texture;
|
|
285
|
+
}
|
|
243
286
|
} else if (props.texture) {
|
|
244
|
-
|
|
287
|
+
if (isElement(props.texture)) {
|
|
288
|
+
const textureInstance = props.texture.componentInstance;
|
|
289
|
+
textureInstance.subjectInit
|
|
290
|
+
.subscribe((value) => {
|
|
291
|
+
console.log('a', value?.width)
|
|
292
|
+
})
|
|
293
|
+
this.texture = this.renderer?.generateTexture(props.texture.componentInstance);
|
|
294
|
+
} else {
|
|
295
|
+
this.texture = props.texture;
|
|
296
|
+
}
|
|
245
297
|
}
|
|
246
|
-
|
|
247
298
|
if (props.rectangle !== undefined) {
|
|
248
299
|
const { x, y, width, height } = props.rectangle?.value ?? props.rectangle;
|
|
249
|
-
const texture = await
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
300
|
+
const texture = await setTexture(this.fullProps.image);
|
|
301
|
+
if (texture) {
|
|
302
|
+
this.texture = new Texture({
|
|
303
|
+
source: texture.source,
|
|
304
|
+
frame: new Rectangle(x, y, width, height),
|
|
305
|
+
});
|
|
306
|
+
}
|
|
254
307
|
}
|
|
255
308
|
}
|
|
256
309
|
|
|
257
|
-
onDestroy(): void {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
310
|
+
async onDestroy(parent: Element, afterDestroy: () => void): Promise<void> {
|
|
311
|
+
const _afterDestroy = async () => {
|
|
312
|
+
this.subscriptionSheet.forEach((sub) => sub.unsubscribe());
|
|
313
|
+
this.subscriptionTick.unsubscribe();
|
|
314
|
+
if (this.currentAnimationContainer && this.parent instanceof Container) {
|
|
315
|
+
this.parent.removeChild(this.currentAnimationContainer);
|
|
316
|
+
}
|
|
317
|
+
if (afterDestroy) {
|
|
318
|
+
afterDestroy();
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
await super.onDestroy(parent, _afterDestroy);
|
|
264
322
|
}
|
|
265
323
|
|
|
266
324
|
has(name: string): boolean {
|
|
@@ -295,7 +353,7 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
295
353
|
);
|
|
296
354
|
}
|
|
297
355
|
|
|
298
|
-
const cloneParams =
|
|
356
|
+
const cloneParams = (params);
|
|
299
357
|
|
|
300
358
|
this.removeChildren();
|
|
301
359
|
animation.sprites = [];
|
|
@@ -321,7 +379,12 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
321
379
|
const sound = this.currentAnimation.data.sound;
|
|
322
380
|
|
|
323
381
|
if (sound) {
|
|
324
|
-
|
|
382
|
+
new Howl({
|
|
383
|
+
src: sound,
|
|
384
|
+
autoplay: true,
|
|
385
|
+
loop: false,
|
|
386
|
+
volume: 1,
|
|
387
|
+
})
|
|
325
388
|
}
|
|
326
389
|
|
|
327
390
|
// Updates immediately to avoid flickering
|
|
@@ -396,6 +459,7 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
396
459
|
const widthOfSprite =
|
|
397
460
|
typeof realSize == "number" ? realSize : realSize?.width;
|
|
398
461
|
|
|
462
|
+
|
|
399
463
|
const applyAnchorBySize = () => {
|
|
400
464
|
if (heightOfSprite && this.hitbox) {
|
|
401
465
|
const { spriteWidth, spriteHeight } = data;
|
|
@@ -440,7 +504,9 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
440
504
|
}
|
|
441
505
|
}
|
|
442
506
|
|
|
443
|
-
export interface CanvasSprite extends PixiSprite {
|
|
507
|
+
export interface CanvasSprite extends PixiSprite {
|
|
508
|
+
layout: Layout | null;
|
|
509
|
+
}
|
|
444
510
|
|
|
445
511
|
registerComponent("Sprite", CanvasSprite);
|
|
446
512
|
|
|
@@ -483,6 +549,10 @@ export interface SpritePropsWithSheet
|
|
|
483
549
|
params?: any;
|
|
484
550
|
onFinish?: () => void;
|
|
485
551
|
};
|
|
552
|
+
loader?: {
|
|
553
|
+
onProgress?: (progress: number) => void;
|
|
554
|
+
onComplete?: (texture: Texture) => void;
|
|
555
|
+
};
|
|
486
556
|
}
|
|
487
557
|
|
|
488
558
|
export type SpritePropTypes = SpritePropsWithImage | SpritePropsWithSheet;
|
package/src/components/Text.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { Text as PixiText, TextStyle } from "pixi.js";
|
|
2
|
-
import { createComponent, registerComponent } from "../engine/reactive";
|
|
3
|
-
import { DisplayObject } from "./DisplayObject";
|
|
2
|
+
import { createComponent, registerComponent, Element, Props } from "../engine/reactive";
|
|
3
|
+
import { DisplayObject, ComponentInstance } from "./DisplayObject";
|
|
4
4
|
import { DisplayObjectProps } from "./types/DisplayObject";
|
|
5
5
|
import { Signal } from "@signe/reactive";
|
|
6
|
-
import { on } from "../engine/trigger";
|
|
6
|
+
import { on, isTrigger } from "../engine/trigger";
|
|
7
7
|
|
|
8
8
|
enum TextEffect {
|
|
9
9
|
Typewriter = "typewriter",
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
interface TextProps extends DisplayObjectProps {
|
|
12
|
+
export interface TextProps extends DisplayObjectProps {
|
|
13
13
|
text?: string;
|
|
14
14
|
style?: Partial<TextStyle>;
|
|
15
15
|
color?: string;
|
|
@@ -21,6 +21,7 @@ interface TextProps extends DisplayObjectProps {
|
|
|
21
21
|
onComplete?: () => void;
|
|
22
22
|
skip?: () => void;
|
|
23
23
|
};
|
|
24
|
+
context?: any; // Ensure context is available, ideally typed from a base prop or injected
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
class CanvasText extends DisplayObject(PixiText) {
|
|
@@ -32,9 +33,15 @@ class CanvasText extends DisplayObject(PixiText) {
|
|
|
32
33
|
private typewriterOptions: any = {};
|
|
33
34
|
private skipSignal?: () => void;
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Called when the component is mounted to the scene graph.
|
|
38
|
+
* Initializes the typewriter effect if configured.
|
|
39
|
+
* @param {Element<CanvasText>} element - The element being mounted with parent and props.
|
|
40
|
+
* @param {number} [index] - The index of the component among its siblings.
|
|
41
|
+
*/
|
|
42
|
+
async onMount(element: Element<CanvasText>, index?: number): Promise<void> {
|
|
43
|
+
const { props } = element;
|
|
44
|
+
await super.onMount(element, index);
|
|
38
45
|
const tick: Signal = props.context.tick;
|
|
39
46
|
|
|
40
47
|
if (props.text && props.typewriter) {
|
|
@@ -44,7 +51,7 @@ class CanvasText extends DisplayObject(PixiText) {
|
|
|
44
51
|
// Set typewriter options
|
|
45
52
|
if (props.typewriter) {
|
|
46
53
|
this.typewriterOptions = props.typewriter;
|
|
47
|
-
if (this.typewriterOptions.skip) {
|
|
54
|
+
if (this.typewriterOptions.skip && isTrigger(this.typewriterOptions.skip)) {
|
|
48
55
|
on(this.typewriterOptions.skip, () => {
|
|
49
56
|
this.skipTypewriter();
|
|
50
57
|
});
|
|
@@ -65,8 +72,8 @@ class CanvasText extends DisplayObject(PixiText) {
|
|
|
65
72
|
this.typewriterOptions = props.typewriter;
|
|
66
73
|
}
|
|
67
74
|
}
|
|
68
|
-
if (props.text) {
|
|
69
|
-
this.text = props.text;
|
|
75
|
+
if (props.text !== undefined) {
|
|
76
|
+
this.text = ''+props.text;
|
|
70
77
|
}
|
|
71
78
|
if (props.text !== undefined && props.text !== this.fullText && this.fullProps.typewriter) {
|
|
72
79
|
this.text = "";
|
|
@@ -130,13 +137,26 @@ class CanvasText extends DisplayObject(PixiText) {
|
|
|
130
137
|
this.currentIndex = this.fullText.length;
|
|
131
138
|
}
|
|
132
139
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Called when the component is about to be destroyed.
|
|
142
|
+
* Unsubscribes from the tick observable.
|
|
143
|
+
* @param {Element<any>} parent - The parent element.
|
|
144
|
+
* @param {() => void} [afterDestroy] - An optional callback function to be executed after the component's own destruction logic.
|
|
145
|
+
*/
|
|
146
|
+
async onDestroy(parent: Element<any>, afterDestroy?: () => void): Promise<void> {
|
|
147
|
+
const _afterDestroy = async () => {
|
|
148
|
+
if (this.subscriptionTick) {
|
|
149
|
+
this.subscriptionTick.unsubscribe();
|
|
150
|
+
}
|
|
151
|
+
if (afterDestroy) {
|
|
152
|
+
afterDestroy();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
await super.onDestroy(parent, _afterDestroy);
|
|
136
156
|
}
|
|
137
157
|
}
|
|
138
158
|
|
|
139
|
-
interface CanvasText extends PixiText {}
|
|
159
|
+
// interface CanvasText extends PixiText {} // Removed as it's redundant and causes type conflicts
|
|
140
160
|
|
|
141
161
|
registerComponent("Text", CanvasText);
|
|
142
162
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Texture } from "pixi.js";
|
|
2
|
+
import { h, mount } from "../engine/signal";
|
|
3
|
+
import { useDefineProps } from "../hooks/useProps";
|
|
4
|
+
import { Sprite } from "./Sprite";
|
|
5
|
+
import { effect, Signal, signal } from "@signe/reactive";
|
|
6
|
+
|
|
7
|
+
interface VideoProps {
|
|
8
|
+
src: string;
|
|
9
|
+
paused?: boolean;
|
|
10
|
+
loop?: boolean;
|
|
11
|
+
muted?: boolean;
|
|
12
|
+
loader?: {
|
|
13
|
+
onComplete?: (texture: Texture) => void;
|
|
14
|
+
onProgress?: (progress: number) => void;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function Video(props: VideoProps) {
|
|
19
|
+
const eventsMap = {
|
|
20
|
+
audioprocess: null,
|
|
21
|
+
canplay: null,
|
|
22
|
+
canplaythrough: null,
|
|
23
|
+
complete: null,
|
|
24
|
+
durationchange: null,
|
|
25
|
+
emptied: null,
|
|
26
|
+
ended: null,
|
|
27
|
+
loadeddata: null,
|
|
28
|
+
loadedmetadata: null,
|
|
29
|
+
pause: null,
|
|
30
|
+
play: null,
|
|
31
|
+
playing: null,
|
|
32
|
+
progress: null,
|
|
33
|
+
ratechange: null,
|
|
34
|
+
seeked: null,
|
|
35
|
+
seeking: null,
|
|
36
|
+
stalled: null,
|
|
37
|
+
suspend: null,
|
|
38
|
+
timeupdate: null,
|
|
39
|
+
volumechange: null,
|
|
40
|
+
waiting: null
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const video: Signal<HTMLVideoElement | null> = signal(null)
|
|
44
|
+
const defineProps = useDefineProps(props)
|
|
45
|
+
const { play, loop, muted } = defineProps({
|
|
46
|
+
play: {
|
|
47
|
+
type: Boolean,
|
|
48
|
+
default: true
|
|
49
|
+
},
|
|
50
|
+
loop: {
|
|
51
|
+
type: Boolean,
|
|
52
|
+
default: false
|
|
53
|
+
},
|
|
54
|
+
muted: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
default: false
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
effect(() => {
|
|
61
|
+
const _video = video()
|
|
62
|
+
const state = play()
|
|
63
|
+
if (_video && state !== undefined) {
|
|
64
|
+
if (state) {
|
|
65
|
+
_video.play()
|
|
66
|
+
} else {
|
|
67
|
+
_video.pause()
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (_video && loop()) {
|
|
71
|
+
_video.loop = loop()
|
|
72
|
+
}
|
|
73
|
+
if (_video && muted()) {
|
|
74
|
+
_video.muted = muted()
|
|
75
|
+
}
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
mount(() => {
|
|
79
|
+
return () => {
|
|
80
|
+
for (let event in eventsMap) {
|
|
81
|
+
if (eventsMap[event]) {
|
|
82
|
+
video().removeEventListener(event, eventsMap[event])
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
return h(Sprite, {
|
|
89
|
+
...props,
|
|
90
|
+
image: props.src,
|
|
91
|
+
loader: {
|
|
92
|
+
onComplete: (texture) => {
|
|
93
|
+
const source = texture.source.resource
|
|
94
|
+
video.set(source)
|
|
95
|
+
if (props?.loader?.onComplete) {
|
|
96
|
+
props.loader.onComplete(texture)
|
|
97
|
+
}
|
|
98
|
+
for (let event in eventsMap) {
|
|
99
|
+
if (props[event]) {
|
|
100
|
+
const cb = (ev) => {
|
|
101
|
+
props[event](ev)
|
|
102
|
+
}
|
|
103
|
+
eventsMap[event] = cb
|
|
104
|
+
source.addEventListener(event, cb)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Viewport as PixiViewport } from 'pixi-viewport';
|
|
2
2
|
import { Subscription } from 'rxjs';
|
|
3
|
-
import { createComponent, registerComponent } from '../engine/reactive';
|
|
4
|
-
import { DisplayObject } from './DisplayObject';
|
|
5
|
-
import { effect } from '@signe/reactive';
|
|
3
|
+
import { createComponent, registerComponent, Element, Props } from '../engine/reactive';
|
|
4
|
+
import { DisplayObject, ComponentInstance } from './DisplayObject';
|
|
5
|
+
import { effect, Signal } from '@signe/reactive';
|
|
6
6
|
|
|
7
7
|
const EVENTS = [
|
|
8
8
|
'bounce-x-end',
|
|
@@ -28,6 +28,21 @@ const EVENTS = [
|
|
|
28
28
|
'zoomed-end'
|
|
29
29
|
]
|
|
30
30
|
|
|
31
|
+
export interface ViewportProps extends Props {
|
|
32
|
+
screenWidth?: number;
|
|
33
|
+
screenHeight?: number;
|
|
34
|
+
worldWidth?: number;
|
|
35
|
+
worldHeight?: number;
|
|
36
|
+
clamp?: boolean | {
|
|
37
|
+
left?: number;
|
|
38
|
+
right?: number;
|
|
39
|
+
top?: number;
|
|
40
|
+
bottom?: number;
|
|
41
|
+
};
|
|
42
|
+
context?: any;
|
|
43
|
+
[key: string]: any;
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
export class CanvasViewport extends DisplayObject(PixiViewport) {
|
|
32
47
|
private tickSubscription: Subscription
|
|
33
48
|
overrideProps = ['wheel']
|
|
@@ -48,16 +63,20 @@ export class CanvasViewport extends DisplayObject(PixiViewport) {
|
|
|
48
63
|
onInit(props) {
|
|
49
64
|
super.onInit(props)
|
|
50
65
|
for (let event of EVENTS) {
|
|
51
|
-
|
|
52
|
-
if (props[camelCaseEvent]) {
|
|
53
|
-
this.on(event, props[camelCaseEvent])
|
|
54
|
-
}
|
|
66
|
+
if (props[event]) this.on(event, props[event])
|
|
55
67
|
}
|
|
56
68
|
}
|
|
57
69
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Called when the component is mounted to the scene graph.
|
|
72
|
+
* Initializes viewport settings and subscriptions.
|
|
73
|
+
* @param {Element<CanvasViewport>} element - The element being mounted. Its `props` property (of type ViewportProps) contains component properties and context.
|
|
74
|
+
* @param {number} [index] - The index of the component among its siblings.
|
|
75
|
+
*/
|
|
76
|
+
async onMount(element: Element<CanvasViewport>, index?: number): Promise<void> {
|
|
77
|
+
await super.onMount(element, index);
|
|
78
|
+
const { props } = element;
|
|
79
|
+
const { tick, app, canvasSize } = props.context;
|
|
61
80
|
let isDragging = false
|
|
62
81
|
|
|
63
82
|
effect(() => {
|
|
@@ -65,18 +84,26 @@ export class CanvasViewport extends DisplayObject(PixiViewport) {
|
|
|
65
84
|
this.screenHeight = canvasSize().height
|
|
66
85
|
})
|
|
67
86
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
87
|
+
effect(() => {
|
|
88
|
+
const _app = app()
|
|
89
|
+
if (!_app) return
|
|
90
|
+
|
|
91
|
+
const renderer = _app.renderer
|
|
92
|
+
|
|
93
|
+
renderer.events.domElement.addEventListener(
|
|
94
|
+
'wheel',
|
|
95
|
+
this.input.wheelFunction
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
this.options.events = renderer.events
|
|
99
|
+
})
|
|
73
100
|
|
|
74
101
|
this.tickSubscription = tick.observable.subscribe(({ value }) => {
|
|
75
102
|
this.update(value.timestamp)
|
|
76
103
|
})
|
|
77
104
|
|
|
78
105
|
element.props.context.viewport = this
|
|
79
|
-
this.updateViewportSettings(
|
|
106
|
+
this.updateViewportSettings(props)
|
|
80
107
|
}
|
|
81
108
|
|
|
82
109
|
onUpdate(props) {
|
|
@@ -97,15 +124,11 @@ export class CanvasViewport extends DisplayObject(PixiViewport) {
|
|
|
97
124
|
if (props.worldHeight !== undefined) {
|
|
98
125
|
this.worldHeight = props.worldHeight
|
|
99
126
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
// } else {
|
|
104
|
-
// this.drag(props.drag)
|
|
105
|
-
// }
|
|
106
|
-
// }
|
|
127
|
+
if (props.drag) {
|
|
128
|
+
this.drag(props.drag)
|
|
129
|
+
}
|
|
107
130
|
if (props.clamp) {
|
|
108
|
-
this.clamp(props.clamp)
|
|
131
|
+
this.clamp(props.clamp.value ?? props.clamp)
|
|
109
132
|
}
|
|
110
133
|
if (props.wheel) {
|
|
111
134
|
if (props.wheel === true) {
|
|
@@ -130,30 +153,23 @@ export class CanvasViewport extends DisplayObject(PixiViewport) {
|
|
|
130
153
|
}
|
|
131
154
|
}
|
|
132
155
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Called when the component is about to be destroyed.
|
|
158
|
+
* Unsubscribes from the tick observable.
|
|
159
|
+
* @param {Element<any>} parent - The parent element.
|
|
160
|
+
* @param {() => void} [afterDestroy] - An optional callback function to be executed after the component's own destruction logic.
|
|
161
|
+
*/
|
|
162
|
+
async onDestroy(parent: Element<any>, afterDestroy?: () => void): Promise<void> {
|
|
163
|
+
const _afterDestroy = async () => {
|
|
164
|
+
this.tickSubscription.unsubscribe()
|
|
165
|
+
afterDestroy()
|
|
166
|
+
}
|
|
167
|
+
await super.onDestroy(parent, _afterDestroy);
|
|
136
168
|
}
|
|
137
169
|
}
|
|
138
170
|
|
|
139
|
-
export interface CanvasViewport extends PixiViewport { }
|
|
140
|
-
|
|
141
171
|
registerComponent('Viewport', CanvasViewport)
|
|
142
172
|
|
|
143
|
-
export interface ViewportProps {
|
|
144
|
-
screenWidth?: number;
|
|
145
|
-
screenHeight?: number;
|
|
146
|
-
worldWidth?: number;
|
|
147
|
-
worldHeight?: number;
|
|
148
|
-
clamp?: boolean | {
|
|
149
|
-
left?: number;
|
|
150
|
-
right?: number;
|
|
151
|
-
top?: number;
|
|
152
|
-
bottom?: number;
|
|
153
|
-
};
|
|
154
|
-
[key: string]: any;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
173
|
export function Viewport(props: ViewportProps) {
|
|
158
174
|
return createComponent('Viewport', props);
|
|
159
175
|
}
|
package/src/components/index.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
export { Canvas } from './Canvas'
|
|
2
2
|
export { Container } from './Container'
|
|
3
|
-
export { Graphics, Rect, Circle, Ellipse, Triangle, Svg
|
|
3
|
+
export { Graphics, Rect, Circle, Ellipse, Triangle, Svg } from './Graphic'
|
|
4
|
+
export { Mesh } from './Mesh'
|
|
4
5
|
export { Scene } from './Scene'
|
|
5
6
|
export { ParticlesEmitter } from './ParticleEmitter'
|
|
6
7
|
export { Sprite } from './Sprite'
|
|
8
|
+
export { Video } from './Video'
|
|
7
9
|
export { Text } from './Text'
|
|
8
10
|
export { TilingSprite } from './TilingSprite'
|
|
9
11
|
export { Viewport } from './Viewport'
|
|
10
12
|
export { NineSliceSprite } from './NineSliceSprite'
|
|
11
|
-
export { type ComponentInstance } from './DisplayObject'
|
|
13
|
+
export { type ComponentInstance } from './DisplayObject'
|
|
14
|
+
export { DOMContainer } from './DOMContainer'
|
|
15
|
+
export { DOMElement } from './DOMElement'
|
|
16
|
+
export { Button, ButtonState, type ButtonProps, type ButtonStyle } from './Button'
|
|
@@ -1,18 +1,43 @@
|
|
|
1
1
|
import * as PIXI from "pixi.js";
|
|
2
2
|
import { SignalOrPrimitive } from ".";
|
|
3
|
+
import { DragProps } from "../../directives/Drag";
|
|
4
|
+
import { ViewportFollowProps } from "../../directives/ViewportFollow";
|
|
3
5
|
|
|
4
6
|
export type FlexDirection = 'row' | 'column' | 'row-reverse' | 'column-reverse';
|
|
5
7
|
export type JustifyContent = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around';
|
|
6
8
|
export type AlignContent = 'flex-start' | 'flex-end' | 'center' | 'space-between' | 'space-around';
|
|
7
9
|
export type Size = number | `${number}%`
|
|
8
10
|
export type EdgeSize = SignalOrPrimitive<Size | [Size, Size] | [Size, Size, Size, Size]>
|
|
11
|
+
export type ObjectFit = 'contain' | 'cover' | 'fill' | 'none' | 'scale-down';
|
|
12
|
+
export type ObjectPosition = string;
|
|
13
|
+
export type TransformOrigin = string;
|
|
14
|
+
export type PositionType = 'relative' | 'absolute' | 'static';
|
|
9
15
|
|
|
10
16
|
export interface DisplayObjectProps {
|
|
17
|
+
attach?: any;
|
|
11
18
|
ref?: string;
|
|
12
19
|
x?: SignalOrPrimitive<number>;
|
|
13
20
|
y?: SignalOrPrimitive<number>;
|
|
14
21
|
width?: SignalOrPrimitive<Size>;
|
|
15
22
|
height?: SignalOrPrimitive<Size>;
|
|
23
|
+
minWidth?: SignalOrPrimitive<Size>;
|
|
24
|
+
minHeight?: SignalOrPrimitive<Size>;
|
|
25
|
+
maxWidth?: SignalOrPrimitive<Size>;
|
|
26
|
+
maxHeight?: SignalOrPrimitive<Size>;
|
|
27
|
+
aspectRatio?: SignalOrPrimitive<number>;
|
|
28
|
+
flexGrow?: SignalOrPrimitive<number>;
|
|
29
|
+
flexShrink?: SignalOrPrimitive<number>;
|
|
30
|
+
flexBasis?: SignalOrPrimitive<Size>;
|
|
31
|
+
rowGap?: SignalOrPrimitive<number>;
|
|
32
|
+
columnGap?: SignalOrPrimitive<number>;
|
|
33
|
+
positionType?: PositionType;
|
|
34
|
+
top?: SignalOrPrimitive<Size>;
|
|
35
|
+
right?: SignalOrPrimitive<Size>;
|
|
36
|
+
bottom?: SignalOrPrimitive<Size>;
|
|
37
|
+
left?: SignalOrPrimitive<Size>;
|
|
38
|
+
objectFit?: ObjectFit;
|
|
39
|
+
objectPosition?: ObjectPosition;
|
|
40
|
+
transformOrigin?: TransformOrigin;
|
|
16
41
|
children?: any[];
|
|
17
42
|
flexDirection?: FlexDirection;
|
|
18
43
|
justifyContent?: JustifyContent;
|
|
@@ -36,6 +61,11 @@ export interface DisplayObjectProps {
|
|
|
36
61
|
blendMode?: SignalOrPrimitive<PIXI.BLEND_MODES>;
|
|
37
62
|
blur?: SignalOrPrimitive<number>;
|
|
38
63
|
|
|
64
|
+
// Directives
|
|
65
|
+
drag?: DragProps;
|
|
66
|
+
viewportFollow?: ViewportFollowProps;
|
|
67
|
+
|
|
68
|
+
// Events
|
|
39
69
|
click?: PIXI.FederatedEventHandler;
|
|
40
70
|
mousedown?: PIXI.FederatedEventHandler;
|
|
41
71
|
mouseenter?: PIXI.FederatedEventHandler;
|