canvasengine 2.0.0-rc.1 → 2.0.0-rc.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/components/Container.d.ts +25 -0
  2. package/dist/components/Container.d.ts.map +1 -0
  3. package/dist/components/DOMContainer.d.ts +28 -0
  4. package/dist/components/DOMContainer.d.ts.map +1 -0
  5. package/dist/components/DOMSprite.d.ts.map +1 -1
  6. package/dist/components/DisplayObject.d.ts +18 -0
  7. package/dist/components/DisplayObject.d.ts.map +1 -0
  8. package/dist/components/Graphic.d.ts.map +1 -1
  9. package/dist/components/Mesh.d.ts +138 -0
  10. package/dist/components/Mesh.d.ts.map +1 -0
  11. package/dist/components/Sprite.d.ts +182 -0
  12. package/dist/components/Sprite.d.ts.map +1 -0
  13. package/dist/components/Viewport.d.ts +52 -0
  14. package/dist/components/Viewport.d.ts.map +1 -0
  15. package/dist/components/index.d.ts +1 -1
  16. package/dist/components/index.d.ts.map +1 -1
  17. package/dist/directives/Controls.d.ts +1 -1
  18. package/dist/engine/reactive.d.ts +5 -1
  19. package/dist/engine/reactive.d.ts.map +1 -1
  20. package/dist/engine/signal.d.ts +1 -0
  21. package/dist/engine/signal.d.ts.map +1 -1
  22. package/dist/hooks/useProps.d.ts.map +1 -1
  23. package/dist/index.global.js +10 -10
  24. package/dist/index.global.js.map +1 -1
  25. package/dist/index.js +6843 -6720
  26. package/dist/index.js.map +1 -1
  27. package/dist/utils/RadialGradient.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/src/components/Container.ts +10 -2
  30. package/src/components/DOMContainer.ts +8 -0
  31. package/src/components/DOMSprite.ts +11 -7
  32. package/src/components/DisplayObject.ts +1 -1
  33. package/src/components/Graphic.ts +6 -0
  34. package/src/components/Mesh.ts +38 -21
  35. package/src/components/Viewport.ts +4 -4
  36. package/src/components/index.ts +1 -1
  37. package/src/engine/reactive.ts +273 -53
  38. package/src/engine/signal.ts +74 -4
  39. package/src/hooks/useProps.ts +18 -6
  40. package/tsconfig.json +5 -1
@@ -50,7 +50,7 @@ export declare class RadialGradient {
50
50
  y: number;
51
51
  };
52
52
  }): {
53
- texture: Texture<import('pixi.js').TextureSource<any>> | null;
53
+ texture: Texture<import('pixi.js').TextureSource<any>>;
54
54
  matrix: Matrix;
55
55
  };
56
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "canvasengine",
3
- "version": "2.0.0-rc.1",
3
+ "version": "2.0.0-rc.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { Container as PixiContainer } from "pixi.js";
1
+ import { Container as PixiContainer, type ContainerChild } from "pixi.js";
2
2
  import { createComponent, registerComponent } from "../engine/reactive";
3
3
  import { DisplayObject } from "./DisplayObject";
4
4
  import { ComponentFunction } from "../engine/signal";
@@ -6,8 +6,16 @@ import { DisplayObjectProps } from "./types/DisplayObject";
6
6
  import { setObservablePoint } from "../engine/utils";
7
7
  import { isPercent } from "../utils/functions";
8
8
 
9
- interface ContainerProps extends DisplayObjectProps {
9
+ export interface ContainerProps extends DisplayObjectProps {
10
10
  sortableChildren?: boolean;
11
+ /**
12
+ * Native PixiJS display objects to add to this container when it mounts.
13
+ *
14
+ * This is an escape hatch for rendering PixiJS objects directly inside the
15
+ * CanvasEngine scene graph. CanvasEngine does not manage these children's
16
+ * props or lifecycle; destroy or update them manually when needed.
17
+ */
18
+ pixiChildren?: ContainerChild[];
11
19
  }
12
20
 
13
21
  export class CanvasContainer extends DisplayObject(PixiContainer) {
@@ -343,6 +343,14 @@ export class CanvasDOMContainer extends DisplayObject(PixiDOMContainer) {
343
343
  }
344
344
 
345
345
  async onMount(element: Element<any>, index?: number) {
346
+ const parentTag = element.parent?.tag;
347
+ if (parentTag === "DOMContainer" || parentTag === "DOMElement") {
348
+ this.onUpdate(element.props);
349
+ this.syncCanvasSizeEffect();
350
+ this.applyElementSize();
351
+ return;
352
+ }
353
+
346
354
  await super.onMount(element, index);
347
355
  this.syncCanvasSizeEffect();
348
356
  this.applyElementSize();
@@ -515,7 +515,11 @@ export class CanvasDOMSprite extends CanvasDOMElement {
515
515
  if (resolvedSheet?.definition !== undefined) {
516
516
  const resolvedDefinition = this.resolveSheetDefinition(resolvedSheet.definition);
517
517
  if (resolvedDefinition instanceof Promise) {
518
- void this.setSheetDefinition(resolvedDefinition);
518
+ void resolvedDefinition.then((definition) => {
519
+ if (definition) {
520
+ void this.setSheetDefinition(definition);
521
+ }
522
+ });
519
523
  } else if (resolvedDefinition && resolvedDefinition !== this.sheetDefinition) {
520
524
  void this.setSheetDefinition(resolvedDefinition);
521
525
  }
@@ -570,7 +574,7 @@ export class CanvasDOMSprite extends CanvasDOMElement {
570
574
  }
571
575
  }
572
576
 
573
- private resolveValue<T>(value: T | Signal<T> | { value?: T } | undefined): T | undefined {
577
+ private resolveValue<T = any>(value: any): T | undefined {
574
578
  if (value === undefined) return undefined;
575
579
  const resolved = isSignal(value as any) ? (value as any)() : value;
576
580
  if (resolved && typeof resolved === "object" && "value" in (resolved as any)) {
@@ -687,9 +691,9 @@ export class CanvasDOMSprite extends CanvasDOMElement {
687
691
  ].some((value) => value !== undefined);
688
692
 
689
693
  if (hasTransformProps) {
690
- let x = this.resolveValue(props.x) ?? 0;
691
- let y = this.resolveValue(props.y) ?? 0;
692
- const roundPixels = this.resolveValue(props.roundPixels);
694
+ let x = this.resolveValue<number>(props.x) ?? 0;
695
+ let y = this.resolveValue<number>(props.y) ?? 0;
696
+ const roundPixels = this.resolveValue<boolean>(props.roundPixels);
693
697
  if (roundPixels) {
694
698
  x = Math.round(x);
695
699
  y = Math.round(y);
@@ -698,8 +702,8 @@ export class CanvasDOMSprite extends CanvasDOMElement {
698
702
  const scale = this.resolvePoint(props.scale) ?? { x: 1, y: 1 };
699
703
  const skew = this.resolvePoint(props.skew);
700
704
 
701
- const angle = this.resolveValue(props.angle);
702
- const rotation = this.resolveValue(props.rotation);
705
+ const angle = this.resolveValue<number>(props.angle);
706
+ const rotation = this.resolveValue<number>(props.rotation);
703
707
  const rotationDeg = angle !== undefined
704
708
  ? angle
705
709
  : rotation !== undefined
@@ -100,7 +100,7 @@ export const EVENTS = [
100
100
 
101
101
  export type OnHook = (() => void) | (() => Promise<void> | void);
102
102
 
103
- export function DisplayObject(extendClass) {
103
+ export function DisplayObject(extendClass): any {
104
104
  return class DisplayObject extends extendClass {
105
105
  #canvasContext: {
106
106
  [key: string]: any;
@@ -88,6 +88,9 @@ class CanvasGraphics extends DisplayObject(PixiGraphics) {
88
88
  */
89
89
  async onMount(element: Element<any>, index?: number): Promise<void> {
90
90
  await super.onMount(element, index);
91
+ if (this.destroyed || !this.parent) {
92
+ return;
93
+ }
91
94
  const { props, propObservables } = element;
92
95
 
93
96
  // Use original signals from propObservables if available, otherwise create new ones
@@ -111,6 +114,9 @@ class CanvasGraphics extends DisplayObject(PixiGraphics) {
111
114
  if (typeof w == 'string' || typeof h == 'string') {
112
115
  return
113
116
  }
117
+ if (this.destroyed || !this.parent) {
118
+ return
119
+ }
114
120
  this.clear();
115
121
  props.draw?.(this, w, h, a);
116
122
  this.subjectInit.next(this)
@@ -1,9 +1,8 @@
1
- import { Effect, effect } from "@signe/reactive";
1
+ import { isSignal } from "@signe/reactive";
2
2
  import { Mesh as PixiMesh, Geometry, Shader, Texture, Assets, BLEND_MODES } from "pixi.js";
3
3
  import { createComponent, Element, registerComponent } from "../engine/reactive";
4
4
  import { ComponentInstance, DisplayObject } from "./DisplayObject";
5
5
  import { DisplayObjectProps } from "./types/DisplayObject";
6
- import { useProps } from "../hooks/useProps";
7
6
  import { SignalOrPrimitive } from "./types";
8
7
  import { ComponentFunction } from "../engine/signal";
9
8
 
@@ -13,19 +12,31 @@ import { ComponentFunction } from "../engine/signal";
13
12
  */
14
13
  interface MeshProps extends DisplayObjectProps {
15
14
  /** The geometry defining the mesh structure (vertices, indices, UVs, etc.) */
16
- geometry?: Geometry;
15
+ geometry?: SignalOrPrimitive<Geometry>;
17
16
  /** The shader to render the mesh with */
18
- shader?: Shader;
17
+ shader?: SignalOrPrimitive<Shader>;
19
18
  /** The texture to apply to the mesh */
20
- texture?: Texture | string;
19
+ texture?: SignalOrPrimitive<Texture | string>;
21
20
  /** The image URL to load as texture */
22
- image?: string;
21
+ image?: SignalOrPrimitive<string>;
23
22
  /** The tint color to apply to the mesh */
24
23
  tint?: SignalOrPrimitive<number>;
25
24
  /** Whether to round pixels for sharper rendering */
26
25
  roundPixels?: SignalOrPrimitive<boolean>;
27
26
  }
28
27
 
28
+ const resolveProp = <T>(value: SignalOrPrimitive<T> | undefined): T | undefined => {
29
+ return isSignal(value as any) ? (value as any)() : value as T | undefined;
30
+ };
31
+
32
+ const isValidGeometry = (value: Geometry | undefined): value is Geometry => {
33
+ if (!value) return false;
34
+ if (value instanceof Geometry) return true;
35
+
36
+ const geometry = value as any;
37
+ return typeof geometry.on === 'function' && typeof geometry.off === 'function';
38
+ };
39
+
29
40
  /**
30
41
  * Canvas Mesh component class that extends DisplayObject with PixiMesh functionality.
31
42
  * This component allows rendering of custom 3D meshes with shaders and textures.
@@ -87,17 +98,19 @@ class CanvasMesh extends DisplayObject(PixiMesh) {
87
98
  super.onInit(props);
88
99
 
89
100
  // Set initial geometry if provided
90
- if (props.geometry) {
101
+ const geometry = resolveProp(props.geometry);
102
+ if (isValidGeometry(geometry)) {
91
103
  try {
92
- this.geometry = props.geometry;
104
+ this.geometry = geometry;
93
105
  } catch (error) {
94
106
  console.warn('Failed to set geometry:', error);
95
107
  }
96
108
  }
97
109
 
98
110
  // Set initial shader if provided
99
- if (props.shader) {
100
- this.shader = props.shader;
111
+ const shader = resolveProp(props.shader);
112
+ if (shader) {
113
+ this.shader = shader;
101
114
  }
102
115
  }
103
116
 
@@ -119,28 +132,32 @@ class CanvasMesh extends DisplayObject(PixiMesh) {
119
132
  super.onUpdate(props);
120
133
 
121
134
  // Handle geometry updates
122
- if (props.geometry) {
135
+ const geometry = resolveProp(props.geometry);
136
+ if (isValidGeometry(geometry)) {
123
137
  try {
124
- this.geometry = props.geometry;
138
+ this.geometry = geometry;
125
139
  } catch (error) {
126
140
  console.warn('Failed to update geometry:', error);
127
141
  }
128
142
  }
129
143
 
130
144
  // Handle shader/material updates
131
- if (props.shader) {
132
- this.shader = props.shader;
145
+ const shader = resolveProp(props.shader);
146
+ if (shader) {
147
+ this.shader = shader;
133
148
  }
134
149
 
135
150
  // Handle texture updates
136
- if (props.texture) {
137
- if (typeof props.texture === 'string') {
138
- this.texture = await Assets.load(props.texture);
151
+ const texture = resolveProp(props.texture);
152
+ const image = resolveProp(props.image);
153
+ if (texture) {
154
+ if (typeof texture === 'string') {
155
+ this.texture = await Assets.load(texture);
139
156
  } else {
140
- this.texture = props.texture;
157
+ this.texture = texture;
141
158
  }
142
- } else if (props.image) {
143
- this.texture = await Assets.load(props.image);
159
+ } else if (image) {
160
+ this.texture = await Assets.load(image);
144
161
  }
145
162
 
146
163
  // Handle tint updates
@@ -219,4 +236,4 @@ export const Mesh: ComponentFunction<MeshProps> = (props) => {
219
236
  export { CanvasMesh };
220
237
 
221
238
  // Export the props interface for TypeScript users
222
- export type { MeshProps };
239
+ export type { MeshProps };
@@ -181,10 +181,10 @@ export class CanvasViewport extends DisplayObject(Container) {
181
181
 
182
182
  private updateMask() {
183
183
  if (!this.#mask) return
184
- this.#mask.clear()
185
- this.#mask.beginFill(0xffffff)
186
- this.#mask.drawRect(0, 0, this.viewport.screenWidth, this.viewport.screenHeight)
187
- this.#mask.endFill()
184
+ this.#mask
185
+ .clear()
186
+ .rect(0, 0, this.viewport.screenWidth, this.viewport.screenHeight)
187
+ .fill(0xffffff)
188
188
  }
189
189
 
190
190
  /**
@@ -1,5 +1,5 @@
1
1
  export { Canvas } from './Canvas'
2
- export { Container } from './Container'
2
+ export { Container, type ContainerProps } from './Container'
3
3
  export { Graphics, Rect, Circle, Ellipse, Triangle, Svg } from './Graphic'
4
4
  export { Mesh } from './Mesh'
5
5
  export { Scene } from './Scene'