canvasengine 2.0.0-beta.19 → 2.0.0-beta.20

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.js CHANGED
@@ -99,7 +99,7 @@ function isFunction(val) {
99
99
  return {}.toString.call(val) === "[object Function]";
100
100
  }
101
101
  function isObject(val) {
102
- return typeof val == "object" && val != null && !Array.isArray(val);
102
+ return typeof val == "object" && val != null && !Array.isArray(val) && val.constructor === Object;
103
103
  }
104
104
  function set(obj, path, value, onlyPlainObject = false) {
105
105
  if (Object(obj) !== obj) return obj;
@@ -1170,7 +1170,7 @@ function loop(itemsSubject, createElementFn) {
1170
1170
  let elements = [];
1171
1171
  let elementMap = /* @__PURE__ */ new Map();
1172
1172
  let isFirstSubscription = true;
1173
- const isArraySignal = (signal9) => Array.isArray(signal9());
1173
+ const isArraySignal = (signal10) => Array.isArray(signal10());
1174
1174
  return new Observable((subscriber) => {
1175
1175
  const subscription = isArraySignal(itemsSubject) ? itemsSubject.observable.subscribe((change) => {
1176
1176
  if (isFirstSubscription) {
@@ -1499,6 +1499,7 @@ var EVENTS = ["load", "loaderror", "playerror", "play", "end", "pause", "stop",
1499
1499
  var Sound = class extends Directive {
1500
1500
  constructor() {
1501
1501
  super(...arguments);
1502
+ this.sounds = [];
1502
1503
  this.eventsFn = [];
1503
1504
  this.maxVolume = 1;
1504
1505
  this.maxDistance = 100;
@@ -1509,20 +1510,28 @@ var Sound = class extends Directive {
1509
1510
  const { props } = element;
1510
1511
  const tick2 = props.context.tick;
1511
1512
  const propsSound = props.sound.value ?? props.sound;
1513
+ if (!propsSound.src) {
1514
+ return;
1515
+ }
1512
1516
  const { src, autoplay, loop: loop2, volume, spatial } = propsSound;
1513
- this.sound = new Howl({
1514
- src,
1515
- autoplay,
1516
- loop: loop2,
1517
- volume
1518
- });
1519
- for (let event of EVENTS) {
1520
- if (!propsSound[event]) continue;
1521
- const fn = propsSound[event];
1522
- this.eventsFn.push(fn);
1523
- this.sound.on(event, fn);
1517
+ const sources = Array.isArray(src) ? src : [src];
1518
+ for (const source of sources) {
1519
+ if (!source) continue;
1520
+ const sound = new Howl({
1521
+ src: source,
1522
+ autoplay,
1523
+ loop: loop2,
1524
+ volume
1525
+ });
1526
+ for (let event of EVENTS) {
1527
+ if (!propsSound[event]) continue;
1528
+ const fn = propsSound[event];
1529
+ this.eventsFn.push(fn);
1530
+ sound.on(event, fn);
1531
+ }
1532
+ this.sounds.push(sound);
1524
1533
  }
1525
- if (spatial) {
1534
+ if (spatial && this.sounds.length > 0) {
1526
1535
  const { soundListenerPosition } = props.context;
1527
1536
  if (!soundListenerPosition) {
1528
1537
  throw new error("SoundListenerPosition directive is required for spatial sound in component parent");
@@ -1533,34 +1542,43 @@ var Sound = class extends Directive {
1533
1542
  const { x, y } = element.componentInstance;
1534
1543
  const distance = calculateDistance(x, y, listenerX(), listenerY());
1535
1544
  const volume2 = Math.max(this.maxVolume - distance / this.maxDistance, 0);
1536
- this.sound.volume(volume2);
1545
+ this.sounds.forEach((sound) => sound.volume(volume2));
1537
1546
  }).subscription;
1538
1547
  }
1548
+ this.onUpdate(propsSound);
1539
1549
  }
1540
1550
  onUpdate(props) {
1541
- const { volume, loop: loop2, mute, seek, playing, rate, spatial } = props.value ?? props;
1542
- if (volume != void 0) this.sound.volume(volume);
1543
- if (loop2 != void 0) this.sound.loop(loop2);
1544
- if (mute != void 0) this.sound.mute(mute);
1545
- if (seek != void 0) this.sound.seek(seek);
1546
- if (playing != void 0) {
1547
- if (playing) this.sound.play();
1548
- else this.sound.pause();
1549
- }
1551
+ const soundProps = props.value ?? props;
1552
+ const { volume, loop: loop2, mute, seek, playing, rate, spatial } = soundProps;
1553
+ this.sounds.forEach((sound) => {
1554
+ if (volume !== void 0) sound.volume(volume);
1555
+ if (loop2 !== void 0) sound.loop(loop2);
1556
+ if (mute !== void 0) sound.mute(mute);
1557
+ if (seek !== void 0) sound.seek(seek);
1558
+ if (playing !== void 0) {
1559
+ if (playing) sound.play();
1560
+ else sound.pause();
1561
+ }
1562
+ if (rate !== void 0) sound.rate(rate);
1563
+ });
1550
1564
  if (spatial) {
1551
1565
  this.maxVolume = spatial.maxVolume ?? this.maxVolume;
1552
1566
  this.maxDistance = spatial.maxDistance ?? this.maxDistance;
1553
1567
  }
1554
- if (rate != void 0) this.sound.rate(rate);
1555
1568
  }
1556
1569
  onDestroy() {
1557
- this.sound.stop();
1558
- this.tickSubscription?.unsubscribe();
1559
- for (let event of EVENTS) {
1560
- if (this.eventsFn[event]) {
1561
- this.sound.off(event, this.eventsFn[event]);
1570
+ this.sounds.forEach((sound) => {
1571
+ sound.stop();
1572
+ for (let event of EVENTS) {
1573
+ const eventFn = this.eventsFn.find((fn) => fn === this.eventsFn[event]);
1574
+ if (eventFn) {
1575
+ sound.off(event, eventFn);
1576
+ }
1562
1577
  }
1563
- }
1578
+ });
1579
+ this.sounds = [];
1580
+ this.eventsFn = [];
1581
+ this.tickSubscription?.unsubscribe();
1564
1582
  }
1565
1583
  };
1566
1584
  var SoundListenerPosition = class extends Directive {
@@ -1929,7 +1947,6 @@ import { Container as Container3 } from "pixi.js";
1929
1947
 
1930
1948
  // src/components/DisplayObject.ts
1931
1949
  import { signal as signal4 } from "@signe/reactive";
1932
- import { DropShadowFilter } from "pixi-filters";
1933
1950
  import { BlurFilter, ObservablePoint } from "pixi.js";
1934
1951
 
1935
1952
  // src/utils/functions.ts
@@ -1942,6 +1959,7 @@ function isPercent(value) {
1942
1959
  }
1943
1960
 
1944
1961
  // src/components/DisplayObject.ts
1962
+ import { BehaviorSubject } from "rxjs";
1945
1963
  var EVENTS2 = [
1946
1964
  "added",
1947
1965
  "childAdded",
@@ -2030,10 +2048,16 @@ function DisplayObject(extendClass) {
2030
2048
  this.layout = null;
2031
2049
  this.onBeforeDestroy = null;
2032
2050
  this.onAfterMount = null;
2051
+ this.subjectInit = new BehaviorSubject(null);
2052
+ this.disableLayout = false;
2033
2053
  }
2034
2054
  get deltaRatio() {
2035
2055
  return __privateGet(this, _canvasContext)?.scheduler?.tick.value.deltaRatio;
2036
2056
  }
2057
+ get parentIsFlex() {
2058
+ if (this.disableLayout) return false;
2059
+ return this.parent?.isFlex;
2060
+ }
2037
2061
  onInit(props) {
2038
2062
  this._id = props.id;
2039
2063
  for (let event of EVENTS2) {
@@ -2052,13 +2076,18 @@ function DisplayObject(extendClass) {
2052
2076
  this.layout = {};
2053
2077
  this.isFlex = true;
2054
2078
  }
2079
+ this.subjectInit.next(this);
2055
2080
  }
2056
2081
  async onMount({ parent, props }, index) {
2057
2082
  __privateSet(this, _canvasContext, props.context);
2058
2083
  if (parent) {
2059
2084
  const instance = parent.componentInstance;
2060
- if (instance.isFlex && !this.layout) {
2061
- this.layout = {};
2085
+ if (instance.isFlex && !this.layout && !this.disableLayout) {
2086
+ try {
2087
+ this.layout = {};
2088
+ } catch (error2) {
2089
+ console.warn("Failed to set layout:", error2);
2090
+ }
2062
2091
  }
2063
2092
  if (index === void 0) {
2064
2093
  instance.addChild(this);
@@ -2137,19 +2166,9 @@ function DisplayObject(extendClass) {
2137
2166
  if (props.blendMode) this.blendMode = props.blendMode;
2138
2167
  if (props.filterArea) this.filterArea = props.filterArea;
2139
2168
  const currentFilters = this.filters || [];
2140
- if (props.shadow) {
2141
- let dropShadowFilter = currentFilters.find(
2142
- (filter) => filter instanceof DropShadowFilter
2143
- );
2144
- if (!dropShadowFilter) {
2145
- dropShadowFilter = new DropShadowFilter();
2146
- currentFilters.push(dropShadowFilter);
2147
- }
2148
- Object.assign(dropShadowFilter, props.shadow);
2149
- }
2150
2169
  if (props.blur) {
2151
2170
  let blurFilter = currentFilters.find(
2152
- (filter) => filter instanceof BlurFilter
2171
+ (filter2) => filter2 instanceof BlurFilter
2153
2172
  );
2154
2173
  if (!blurFilter) {
2155
2174
  const options = typeof props.blur === "number" ? {
@@ -2167,7 +2186,7 @@ function DisplayObject(extendClass) {
2167
2186
  await this.onBeforeDestroy();
2168
2187
  }
2169
2188
  super.destroy();
2170
- if (this.onAfterDestroy) this.onAfterDestroy();
2189
+ if (afterDestroy) afterDestroy();
2171
2190
  }
2172
2191
  setFlexDirection(direction) {
2173
2192
  this.layout = { flexDirection: direction };
@@ -2208,7 +2227,7 @@ function DisplayObject(extendClass) {
2208
2227
  }
2209
2228
  setX(x) {
2210
2229
  x = x + this.getWidth() * this._anchorPoints.x;
2211
- if (!this.parent.isFlex) {
2230
+ if (!this.parentIsFlex) {
2212
2231
  this.x = x;
2213
2232
  } else {
2214
2233
  this.x = x;
@@ -2217,7 +2236,7 @@ function DisplayObject(extendClass) {
2217
2236
  }
2218
2237
  setY(y) {
2219
2238
  y = y + this.getHeight() * this._anchorPoints.y;
2220
- if (!this.parent.isFlex) {
2239
+ if (!this.parentIsFlex) {
2221
2240
  this.y = y;
2222
2241
  } else {
2223
2242
  this.y = y;
@@ -2289,7 +2308,7 @@ function DisplayObject(extendClass) {
2289
2308
  }
2290
2309
  setWidth(width) {
2291
2310
  this.displayWidth.set(width);
2292
- if (!this.parent?.isFlex) {
2311
+ if (!this.parentIsFlex) {
2293
2312
  this.width = width;
2294
2313
  } else {
2295
2314
  this.layout = { width };
@@ -2297,7 +2316,7 @@ function DisplayObject(extendClass) {
2297
2316
  }
2298
2317
  setHeight(height) {
2299
2318
  this.displayHeight.set(height);
2300
- if (!this.parent?.isFlex) {
2319
+ if (!this.parentIsFlex) {
2301
2320
  this.height = height;
2302
2321
  } else {
2303
2322
  this.layout = { height };
@@ -2491,17 +2510,102 @@ var Container4 = (props) => {
2491
2510
  };
2492
2511
 
2493
2512
  // src/components/Graphic.ts
2494
- import { effect as effect4 } from "@signe/reactive";
2495
- import { Graphics as PixiGraphics } from "pixi.js";
2513
+ import { effect as effect4, isSignal as isSignal4, signal as signal6 } from "@signe/reactive";
2514
+ import { Assets, Graphics as PixiGraphics } from "pixi.js";
2496
2515
  var CanvasGraphics = class extends DisplayObject(PixiGraphics) {
2497
- onInit(props) {
2498
- super.onInit(props);
2516
+ /**
2517
+ * Initializes the graphics component with reactive width and height handling.
2518
+ *
2519
+ * This method handles different types of width and height props:
2520
+ * - **Numbers**: Direct pixel values
2521
+ * - **Strings with %**: Percentage values that trigger flex layout and use layout box dimensions
2522
+ * - **Signals**: Reactive values that update automatically
2523
+ *
2524
+ * When percentage values are detected, the component:
2525
+ * 1. Sets `display: 'flex'` to enable layout calculations
2526
+ * 2. Listens to layout events to get computed dimensions
2527
+ * 3. Updates internal width/height signals with layout box values
2528
+ *
2529
+ * The draw function receives the reactive width and height signals as parameters.
2530
+ *
2531
+ * @param props - Component properties including width, height, and draw function
2532
+ * @example
2533
+ * ```typescript
2534
+ * // With pixel values
2535
+ * Graphics({ width: 100, height: 50, draw: (g, w, h) => g.rect(0, 0, w(), h()) });
2536
+ *
2537
+ * // With percentage values (uses layout box)
2538
+ * Graphics({ width: "50%", height: "100%", draw: (g, w, h) => g.rect(0, 0, w(), h()) });
2539
+ *
2540
+ * // With signals
2541
+ * const width = signal(100);
2542
+ * Graphics({ width, height: 50, draw: (g, w, h) => g.rect(0, 0, w(), h()) });
2543
+ * ```
2544
+ */
2545
+ async onInit(props) {
2546
+ await super.onInit(props);
2547
+ }
2548
+ /**
2549
+ * Called when the component is mounted to the scene graph.
2550
+ * Creates the reactive effect for drawing using the original signals from propObservables.
2551
+ * @param {Element<DisplayObject>} element - The element being mounted with props and propObservables.
2552
+ * @param {number} [index] - The index of the component among its siblings.
2553
+ */
2554
+ async onMount(element, index) {
2555
+ await super.onMount(element, index);
2556
+ const { props, propObservables } = element;
2557
+ const width = isSignal4(propObservables?.width) ? propObservables.width : signal6(props.width || 0);
2558
+ const height = isSignal4(propObservables?.height) ? propObservables.height : signal6(props.height || 0);
2559
+ this.width = width;
2560
+ this.height = height;
2561
+ const isWidthPercentage = isPercent(width());
2562
+ const isHeightPercentage = isPercent(height());
2499
2563
  if (props.draw) {
2500
2564
  this.clearEffect = effect4(() => {
2565
+ const w = width();
2566
+ const h2 = height();
2567
+ if (typeof w == "string" || typeof h2 == "string") {
2568
+ return;
2569
+ }
2570
+ if (w == 0 || h2 == 0) {
2571
+ return;
2572
+ }
2501
2573
  this.clear();
2502
- props.draw?.(this);
2574
+ props.draw?.(this, w, h2);
2575
+ this.subjectInit.next(this);
2503
2576
  });
2504
2577
  }
2578
+ this.on("layout", (event) => {
2579
+ const layoutBox = event.computedLayout;
2580
+ if (isWidthPercentage && isSignal4(width)) {
2581
+ width.set(layoutBox.width);
2582
+ }
2583
+ if (isHeightPercentage && isSignal4(height)) {
2584
+ height.set(layoutBox.height);
2585
+ }
2586
+ });
2587
+ }
2588
+ /**
2589
+ * Called when component props are updated.
2590
+ * Updates the internal width and height signals when props change.
2591
+ * @param props - Updated properties
2592
+ */
2593
+ onUpdate(props) {
2594
+ super.onUpdate(props);
2595
+ if (props.width !== void 0 && this.width) {
2596
+ if (isSignal4(props.width)) {
2597
+ this.width = props.width;
2598
+ } else {
2599
+ this.width.set(props.width);
2600
+ }
2601
+ }
2602
+ if (props.height !== void 0 && this.height) {
2603
+ if (isSignal4(props.height)) {
2604
+ this.height = props.height;
2605
+ } else {
2606
+ this.height.set(props.height);
2607
+ }
2608
+ }
2505
2609
  }
2506
2610
  /**
2507
2611
  * Called when the component is about to be destroyed.
@@ -2526,16 +2630,16 @@ function Graphics(props) {
2526
2630
  return createComponent("Graphics", props);
2527
2631
  }
2528
2632
  function Rect(props) {
2529
- const { width, height, color, borderRadius, border } = useProps(props, {
2633
+ const { color, borderRadius, border } = useProps(props, {
2530
2634
  borderRadius: null,
2531
2635
  border: null
2532
2636
  });
2533
2637
  return Graphics({
2534
- draw: (g) => {
2638
+ draw: (g, width, height) => {
2535
2639
  if (borderRadius()) {
2536
- g.roundRect(0, 0, width(), height(), borderRadius());
2640
+ g.roundRect(0, 0, width, height, borderRadius());
2537
2641
  } else {
2538
- g.rect(0, 0, width(), height());
2642
+ g.rect(0, 0, width, height);
2539
2643
  }
2540
2644
  if (border) {
2541
2645
  g.stroke(border);
@@ -2571,7 +2675,7 @@ function Ellipse(props) {
2571
2675
  border: null
2572
2676
  });
2573
2677
  return Graphics({
2574
- draw: (g) => drawShape(g, "ellipse", { width, height, color, border }),
2678
+ draw: (g, gWidth, gHeight) => drawShape(g, "ellipse", { width: signal6(gWidth), height: signal6(gHeight), color, border }),
2575
2679
  ...props
2576
2680
  });
2577
2681
  }
@@ -2581,11 +2685,11 @@ function Triangle(props) {
2581
2685
  color: "#000"
2582
2686
  });
2583
2687
  return Graphics({
2584
- draw: (g) => {
2585
- g.moveTo(0, height());
2586
- g.lineTo(width() / 2, 0);
2587
- g.lineTo(width(), height());
2588
- g.lineTo(0, height());
2688
+ draw: (g, gWidth, gHeight) => {
2689
+ g.moveTo(0, gHeight);
2690
+ g.lineTo(gWidth / 2, 0);
2691
+ g.lineTo(gWidth, gHeight);
2692
+ g.lineTo(0, gHeight);
2589
2693
  g.fill(color());
2590
2694
  if (border) {
2591
2695
  g.stroke(border);
@@ -2596,11 +2700,140 @@ function Triangle(props) {
2596
2700
  }
2597
2701
  function Svg(props) {
2598
2702
  return Graphics({
2599
- draw: (g) => g.svg(props.svg),
2703
+ draw: async (g) => {
2704
+ if (props.src) {
2705
+ const svgData = await Assets.load({
2706
+ src: props.src,
2707
+ data: {
2708
+ parseAsGraphicsContext: true
2709
+ }
2710
+ });
2711
+ const graphics = new PixiGraphics(svgData);
2712
+ g.context = graphics.context;
2713
+ } else if (props.content) {
2714
+ g.svg(props.content);
2715
+ } else if (props.svg) {
2716
+ g.svg(props.svg);
2717
+ }
2718
+ },
2600
2719
  ...props
2601
2720
  });
2602
2721
  }
2603
2722
 
2723
+ // src/components/Mesh.ts
2724
+ import { Mesh as PixiMesh, Geometry, Assets as Assets2 } from "pixi.js";
2725
+ var CanvasMesh = class extends DisplayObject(PixiMesh) {
2726
+ /**
2727
+ * Constructor for the CanvasMesh component.
2728
+ * Initializes the PixiMesh with default geometry and shader to prevent errors.
2729
+ *
2730
+ * @example
2731
+ * ```typescript
2732
+ * // This constructor is called internally by the engine
2733
+ * const mesh = new CanvasMesh();
2734
+ * ```
2735
+ */
2736
+ constructor() {
2737
+ super({
2738
+ geometry: new Geometry()
2739
+ });
2740
+ }
2741
+ /**
2742
+ * Initializes the mesh component with the provided properties.
2743
+ * This method is called before onUpdate to set up initial state.
2744
+ *
2745
+ * @param props - The initial properties
2746
+ * @example
2747
+ * ```typescript
2748
+ * // This method is called internally when the component is created
2749
+ * mesh.onInit({
2750
+ * geometry: myGeometry,
2751
+ * texture: "texture.png"
2752
+ * });
2753
+ * ```
2754
+ */
2755
+ onInit(props) {
2756
+ super.onInit(props);
2757
+ if (props.geometry) {
2758
+ try {
2759
+ this.geometry = props.geometry;
2760
+ } catch (error2) {
2761
+ console.warn("Failed to set geometry:", error2);
2762
+ }
2763
+ }
2764
+ if (props.shader) {
2765
+ this.shader = props.shader;
2766
+ }
2767
+ }
2768
+ /**
2769
+ * Updates the mesh component when properties change.
2770
+ * Handles texture loading, shader updates, and other property changes.
2771
+ *
2772
+ * @param props - The updated properties
2773
+ * @example
2774
+ * ```typescript
2775
+ * // This method is called internally when props change
2776
+ * mesh.onUpdate({
2777
+ * tint: 0x00ff00,
2778
+ * texture: "new-texture.png"
2779
+ * });
2780
+ * ```
2781
+ */
2782
+ async onUpdate(props) {
2783
+ super.onUpdate(props);
2784
+ if (props.geometry) {
2785
+ try {
2786
+ this.geometry = props.geometry;
2787
+ } catch (error2) {
2788
+ console.warn("Failed to update geometry:", error2);
2789
+ }
2790
+ }
2791
+ if (props.shader) {
2792
+ this.shader = props.shader;
2793
+ }
2794
+ if (props.texture) {
2795
+ if (typeof props.texture === "string") {
2796
+ this.texture = await Assets2.load(props.texture);
2797
+ } else {
2798
+ this.texture = props.texture;
2799
+ }
2800
+ } else if (props.image) {
2801
+ this.texture = await Assets2.load(props.image);
2802
+ }
2803
+ if (props.tint !== void 0) {
2804
+ this.tint = props.tint;
2805
+ }
2806
+ if (props.blendMode !== void 0) {
2807
+ this.blendMode = props.blendMode;
2808
+ }
2809
+ if (props.roundPixels !== void 0) {
2810
+ this.roundPixels = props.roundPixels;
2811
+ }
2812
+ }
2813
+ /**
2814
+ * Called when the component is about to be destroyed.
2815
+ * Cleans up the draw effect subscription and calls the parent destroy method.
2816
+ *
2817
+ * @param parent - The parent element
2818
+ * @param afterDestroy - Callback function to execute after destruction
2819
+ * @example
2820
+ * ```typescript
2821
+ * // This method is typically called by the engine internally
2822
+ * await mesh.onDestroy(parentElement, () => console.log('Mesh destroyed'));
2823
+ * ```
2824
+ */
2825
+ async onDestroy(parent, afterDestroy) {
2826
+ const _afterDestroyCallback = async () => {
2827
+ afterDestroy();
2828
+ };
2829
+ await super.onDestroy(parent, _afterDestroyCallback);
2830
+ }
2831
+ };
2832
+ registerComponent("Mesh", CanvasMesh);
2833
+ var Mesh = (props) => {
2834
+ return createComponent("Mesh", props);
2835
+ };
2836
+
2604
2837
  // src/engine/signal.ts
2605
2838
  var currentSubscriptionsTracker = null;
2606
2839
  var mountTracker = null;
@@ -2697,20 +2930,20 @@ function ParticlesEmitter(props) {
2697
2930
 
2698
2931
  // src/components/Sprite.ts
2699
2932
  import { Howl as Howl2 } from "howler";
2700
- import { computed, effect as effect6, isSignal as isSignal4 } from "@signe/reactive";
2933
+ import { computed, effect as effect6, isSignal as isSignal5 } from "@signe/reactive";
2701
2934
  import {
2702
- Assets,
2935
+ Assets as Assets3,
2703
2936
  Container as Container5,
2704
2937
  Sprite as PixiSprite,
2705
2938
  Rectangle as Rectangle2,
2706
- Texture as Texture2
2939
+ Texture as Texture3
2707
2940
  } from "pixi.js";
2708
2941
 
2709
2942
  // src/engine/animation.ts
2710
- import { effect as effect5, signal as signal6 } from "@signe/reactive";
2943
+ import { effect as effect5, signal as signal7 } from "@signe/reactive";
2711
2944
  import { animate as animatePopmotion } from "popmotion";
2712
- function isAnimatedSignal(signal9) {
2713
- return signal9.animatedState !== void 0;
2945
+ function isAnimatedSignal(signal10) {
2946
+ return signal10.animatedState !== void 0;
2714
2947
  }
2715
2948
  function animatedSignal(initialValue, options = {}) {
2716
2949
  const state = {
@@ -2719,8 +2952,8 @@ function animatedSignal(initialValue, options = {}) {
2719
2952
  end: initialValue
2720
2953
  };
2721
2954
  let animation;
2722
- const publicSignal = signal6(initialValue);
2723
- const privateSignal = signal6(state);
2955
+ const publicSignal = signal7(initialValue);
2956
+ const privateSignal = signal7(state);
2724
2957
  effect5(() => {
2725
2958
  const currentState = privateSignal();
2726
2959
  publicSignal.set(currentState.current);
@@ -2796,11 +3029,19 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2796
3029
  this.subscriptionSheet = [];
2797
3030
  this.sheetParams = {};
2798
3031
  this.sheetCurrentAnimation = "stand" /* Stand */;
3032
+ this.app = null;
2799
3033
  this.currentAnimationContainer = null;
2800
3034
  }
3035
+ get renderer() {
3036
+ return this.app?.renderer;
3037
+ }
2801
3038
  async createTextures(options) {
2802
3039
  const { width, height, framesHeight, framesWidth, image, offset } = options;
2803
- const texture = await Assets.load(image);
3040
+ if (!image || typeof image !== "string" || image.trim() === "") {
3041
+ console.warn("Invalid image path provided to createTextures:", image);
3042
+ return [];
3043
+ }
3044
+ const texture = await Assets3.load(image);
2804
3045
  const spriteWidth = options.spriteWidth;
2805
3046
  const spriteHeight = options.spriteHeight;
2806
3047
  const frames = [];
@@ -2822,7 +3063,7 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2822
3063
  );
2823
3064
  }
2824
3065
  frames[i].push(
2825
- new Texture2({
3066
+ new Texture3({
2826
3067
  source: texture.source,
2827
3068
  frame: new Rectangle2(rectX, rectY, spriteWidth, spriteHeight)
2828
3069
  })
@@ -2882,6 +3123,7 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2882
3123
  const { props, propObservables } = params;
2883
3124
  const tick2 = props.context.tick;
2884
3125
  const sheet = props.sheet ?? {};
3126
+ this.app = props.context.app();
2885
3127
  if (sheet?.onFinish) {
2886
3128
  this.onFinish = sheet.onFinish;
2887
3129
  }
@@ -2895,7 +3137,7 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2895
3137
  if (sheet.params) {
2896
3138
  for (let key in propObservables?.sheet["params"]) {
2897
3139
  const value = propObservables?.sheet["params"][key];
2898
- if (isSignal4(value)) {
3140
+ if (isSignal5(value)) {
2899
3141
  this.subscriptionSheet.push(
2900
3142
  value.observable.subscribe((value2) => {
2901
3143
  if (this.animations.size == 0) return;
@@ -2931,8 +3173,12 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2931
3173
  async onUpdate(props) {
2932
3174
  super.onUpdate(props);
2933
3175
  const setTexture = async (image) => {
3176
+ if (!image || typeof image !== "string" || image.trim() === "") {
3177
+ console.warn("Invalid image path provided to setTexture:", image);
3178
+ return null;
3179
+ }
2934
3180
  const onProgress = this.fullProps.loader?.onProgress;
2935
- const texture = await Assets.load(image, (progress) => {
3181
+ const texture = await Assets3.load(image, (progress) => {
2936
3182
  if (onProgress) onProgress(progress);
2937
3183
  if (progress == 1) {
2938
3184
  const onComplete = this.fullProps.loader?.onComplete;
@@ -2954,17 +3200,30 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2954
3200
  if (props.hitbox) this.hitbox = props.hitbox;
2955
3201
  if (props.scaleMode) this.baseTexture.scaleMode = props.scaleMode;
2956
3202
  else if (props.image && this.fullProps.rectangle === void 0) {
2957
- this.texture = await setTexture(this.fullProps.image);
3203
+ const texture = await setTexture(this.fullProps.image);
3204
+ if (texture) {
3205
+ this.texture = texture;
3206
+ }
2958
3207
  } else if (props.texture) {
2959
- this.texture = props.texture;
3208
+ if (isElement(props.texture)) {
3209
+ const textureInstance = props.texture.componentInstance;
3210
+ textureInstance.subjectInit.subscribe((value) => {
3211
+ console.log("a", value?.width);
3212
+ });
3213
+ this.texture = this.renderer?.generateTexture(props.texture.componentInstance);
3214
+ } else {
3215
+ this.texture = props.texture;
3216
+ }
2960
3217
  }
2961
3218
  if (props.rectangle !== void 0) {
2962
3219
  const { x, y, width, height } = props.rectangle?.value ?? props.rectangle;
2963
3220
  const texture = await setTexture(this.fullProps.image);
2964
- this.texture = new Texture2({
2965
- source: texture.source,
2966
- frame: new Rectangle2(x, y, width, height)
2967
- });
3221
+ if (texture) {
3222
+ this.texture = new Texture3({
3223
+ source: texture.source,
3224
+ frame: new Rectangle2(x, y, width, height)
3225
+ });
3226
+ }
2968
3227
  }
2969
3228
  }
2970
3229
  async onDestroy(parent, afterDestroy) {
@@ -3108,7 +3367,7 @@ var Sprite2 = (props) => {
3108
3367
  };
3109
3368
 
3110
3369
  // src/components/Video.ts
3111
- import { effect as effect7, signal as signal7 } from "@signe/reactive";
3370
+ import { effect as effect7, signal as signal8 } from "@signe/reactive";
3112
3371
  function Video(props) {
3113
3372
  const eventsMap = {
3114
3373
  audioprocess: null,
@@ -3133,7 +3392,7 @@ function Video(props) {
3133
3392
  volumechange: null,
3134
3393
  waiting: null
3135
3394
  };
3136
- const video = signal7(null);
3395
+ const video = signal8(null);
3137
3396
  const defineProps = useDefineProps(props);
3138
3397
  const { play, loop: loop2, muted } = defineProps({
3139
3398
  play: {
@@ -3203,12 +3462,12 @@ function Video(props) {
3203
3462
  import { Text as PixiText } from "pixi.js";
3204
3463
 
3205
3464
  // src/engine/trigger.ts
3206
- import { effect as effect8, signal as signal8 } from "@signe/reactive";
3465
+ import { effect as effect8, signal as signal9 } from "@signe/reactive";
3207
3466
  function isTrigger(arg) {
3208
3467
  return arg?.start && arg?.listen;
3209
3468
  }
3210
3469
  function trigger(globalConfig) {
3211
- const _signal = signal8({
3470
+ const _signal = signal9({
3212
3471
  config: globalConfig,
3213
3472
  value: 0,
3214
3473
  resolve: (value) => void 0
@@ -3263,12 +3522,12 @@ var CanvasText = class extends DisplayObject(PixiText) {
3263
3522
  /**
3264
3523
  * Called when the component is mounted to the scene graph.
3265
3524
  * Initializes the typewriter effect if configured.
3266
- * @param {Element<CanvasText>} element - The element being mounted. Its `props` property (of type TextProps) contains component properties and context.
3525
+ * @param {Element<CanvasText>} element - The element being mounted with parent and props.
3267
3526
  * @param {number} [index] - The index of the component among its siblings.
3268
3527
  */
3269
3528
  async onMount(element, index) {
3270
- await super.onMount(element, index);
3271
3529
  const { props } = element;
3530
+ await super.onMount(element, index);
3272
3531
  const tick2 = props.context.tick;
3273
3532
  if (props.text && props.typewriter) {
3274
3533
  this.fullText = props.text;
@@ -3276,7 +3535,7 @@ var CanvasText = class extends DisplayObject(PixiText) {
3276
3535
  this.currentIndex = 0;
3277
3536
  if (props.typewriter) {
3278
3537
  this.typewriterOptions = props.typewriter;
3279
- if (this.typewriterOptions.skip) {
3538
+ if (this.typewriterOptions.skip && isTrigger(this.typewriterOptions.skip)) {
3280
3539
  on(this.typewriterOptions.skip, () => {
3281
3540
  this.skipTypewriter();
3282
3541
  });
@@ -3360,8 +3619,12 @@ var CanvasText = class extends DisplayObject(PixiText) {
3360
3619
  */
3361
3620
  async onDestroy(parent, afterDestroy) {
3362
3621
  const _afterDestroy = async () => {
3363
- this.subscriptionTick.unsubscribe();
3364
- afterDestroy();
3622
+ if (this.subscriptionTick) {
3623
+ this.subscriptionTick.unsubscribe();
3624
+ }
3625
+ if (afterDestroy) {
3626
+ afterDestroy();
3627
+ }
3365
3628
  };
3366
3629
  await super.onDestroy(parent, _afterDestroy);
3367
3630
  }
@@ -3372,12 +3635,12 @@ function Text(props) {
3372
3635
  }
3373
3636
 
3374
3637
  // src/components/TilingSprite.ts
3375
- import { TilingSprite as PixiTilingSprite, Texture as Texture3 } from "pixi.js";
3638
+ import { TilingSprite as PixiTilingSprite, Texture as Texture4 } from "pixi.js";
3376
3639
  var CanvasTilingSprite = class extends DisplayObject(PixiTilingSprite) {
3377
3640
  onUpdate(props) {
3378
3641
  super.onUpdate(props);
3379
3642
  if (props.image) {
3380
- this.texture = Texture3.from(props.image);
3643
+ this.texture = Texture4.from(props.image);
3381
3644
  }
3382
3645
  if (props.tileScale) {
3383
3646
  this.tileScale.set(props.tileScale.x, props.tileScale.y);
@@ -3540,7 +3803,7 @@ function Viewport(props) {
3540
3803
  }
3541
3804
 
3542
3805
  // src/components/NineSliceSprite.ts
3543
- import { Assets as Assets2, NineSliceSprite as PixiNineSliceSprite } from "pixi.js";
3806
+ import { Assets as Assets4, NineSliceSprite as PixiNineSliceSprite } from "pixi.js";
3544
3807
  var CanvasNineSliceSprite = class extends DisplayObject(PixiNineSliceSprite) {
3545
3808
  constructor() {
3546
3809
  super({
@@ -3552,7 +3815,7 @@ var CanvasNineSliceSprite = class extends DisplayObject(PixiNineSliceSprite) {
3552
3815
  for (const [key, value] of Object.entries(props)) {
3553
3816
  if (value !== void 0) {
3554
3817
  if (key === "image") {
3555
- this.texture = await Assets2.load(value);
3818
+ this.texture = await Assets4.load(value);
3556
3819
  } else if (key in this) {
3557
3820
  this[key] = value;
3558
3821
  }
@@ -3565,11 +3828,135 @@ function NineSliceSprite(props) {
3565
3828
  return createComponent("NineSliceSprite", props);
3566
3829
  }
3567
3830
 
3831
+ // src/components/DOMContainer.ts
3832
+ import { DOMContainer as PixiDOMContainer } from "pixi.js";
3833
+ var EVENTS4 = [
3834
+ "click",
3835
+ "mouseover",
3836
+ "mouseout",
3837
+ "mouseenter",
3838
+ "mouseleave",
3839
+ "mousemove",
3840
+ "mouseup",
3841
+ "mousedown",
3842
+ "touchstart",
3843
+ "touchend",
3844
+ "touchmove",
3845
+ "touchcancel",
3846
+ "wheel",
3847
+ "scroll",
3848
+ "resize",
3849
+ "focus",
3850
+ "blur",
3851
+ "change",
3852
+ "input",
3853
+ "submit",
3854
+ "reset",
3855
+ "keydown",
3856
+ "keyup",
3857
+ "keypress",
3858
+ "contextmenu",
3859
+ "drag",
3860
+ "dragend",
3861
+ "dragenter",
3862
+ "dragleave",
3863
+ "dragover",
3864
+ "drop",
3865
+ "dragstart",
3866
+ "select",
3867
+ "selectstart",
3868
+ "selectend",
3869
+ "selectall",
3870
+ "selectnone"
3871
+ ];
3872
+ var CanvasDOMContainer = class extends DisplayObject(PixiDOMContainer) {
3873
+ constructor() {
3874
+ super(...arguments);
3875
+ this.disableLayout = true;
3876
+ this.eventListeners = /* @__PURE__ */ new Map();
3877
+ }
3878
+ onInit(props) {
3879
+ super.onInit(props);
3880
+ if (props.element === void 0) {
3881
+ throw new Error("DOMContainer: element is required");
3882
+ }
3883
+ if (typeof props.element === "string") {
3884
+ this.element = document.createElement(props.element);
3885
+ } else {
3886
+ this.element = props.element.value;
3887
+ }
3888
+ for (const event of EVENTS4) {
3889
+ if (props.attrs?.[event]) {
3890
+ const eventHandler = (e) => {
3891
+ props.attrs[event]?.(e);
3892
+ };
3893
+ this.eventListeners.set(event, eventHandler);
3894
+ this.element.addEventListener(event, eventHandler, false);
3895
+ }
3896
+ }
3897
+ }
3898
+ onUpdate(props) {
3899
+ super.onUpdate(props);
3900
+ for (const [key, value] of Object.entries(props.attrs || {})) {
3901
+ if (key === "class") {
3902
+ const classList = value.items || value.value || value;
3903
+ this.element.className = "";
3904
+ if (typeof classList === "string") {
3905
+ this.element.className = classList;
3906
+ } else if (Array.isArray(classList)) {
3907
+ this.element.classList.add(...classList);
3908
+ } else if (typeof classList === "object" && classList !== null) {
3909
+ for (const [className, shouldAdd] of Object.entries(classList)) {
3910
+ if (shouldAdd) {
3911
+ this.element.classList.add(className);
3912
+ }
3913
+ }
3914
+ }
3915
+ } else if (key === "style") {
3916
+ const styleValue = value.items || value.value || value;
3917
+ if (typeof styleValue === "string") {
3918
+ this.element.setAttribute("style", styleValue);
3919
+ } else if (typeof styleValue === "object" && styleValue !== null) {
3920
+ for (const [styleProp, styleVal] of Object.entries(styleValue)) {
3921
+ if (styleVal !== null && styleVal !== void 0) {
3922
+ this.element.style[styleProp] = styleVal;
3923
+ }
3924
+ }
3925
+ }
3926
+ } else if (!EVENTS4.includes(key)) {
3927
+ this.element.setAttribute(key, value);
3928
+ }
3929
+ }
3930
+ if (props.textContent) {
3931
+ this.element.textContent = props.textContent;
3932
+ }
3933
+ if (props.sortableChildren !== void 0) {
3934
+ this.sortableChildren = props.sortableChildren;
3935
+ }
3936
+ }
3937
+ async onDestroy(parent, afterDestroy) {
3938
+ if (this.element) {
3939
+ for (const [event, handler] of this.eventListeners) {
3940
+ this.element.removeEventListener(event, handler, false);
3941
+ }
3942
+ this.eventListeners.clear();
3943
+ }
3944
+ const _afterDestroyCallback = async () => {
3945
+ afterDestroy();
3946
+ };
3947
+ await super.onDestroy(parent, _afterDestroyCallback);
3948
+ }
3949
+ };
3950
+ registerComponent("DOMContainer", CanvasDOMContainer);
3951
+ var DOMContainer = (props) => {
3952
+ return createComponent("DOMContainer", props);
3953
+ };
3954
+
3568
3955
  // src/engine/bootstrap.ts
3569
3956
  import "@pixi/layout";
3570
- import { Application as Application2 } from "pixi.js";
3957
+ import { Application as Application3 } from "pixi.js";
3571
3958
  var bootstrapCanvas = async (rootElement, canvas) => {
3572
- const app = new Application2();
3959
+ const app = new Application3();
3573
3960
  await app.init({
3574
3961
  resizeTo: rootElement,
3575
3962
  autoStart: false
@@ -3620,7 +4007,7 @@ var Easing = {
3620
4007
  };
3621
4008
 
3622
4009
  // src/utils/RadialGradient.ts
3623
- import { Texture as Texture5, ImageSource, DOMAdapter, Matrix } from "pixi.js";
4010
+ import { Texture as Texture6, ImageSource, DOMAdapter, Matrix } from "pixi.js";
3624
4011
  var RadialGradient = class {
3625
4012
  /**
3626
4013
  * Creates a new RadialGradient instance
@@ -3682,7 +4069,7 @@ var RadialGradient = class {
3682
4069
  if (this.ctx && this.gradient) {
3683
4070
  this.ctx.fillStyle = this.gradient;
3684
4071
  this.ctx.fillRect(0, 0, defaultSize, defaultSize);
3685
- this.texture = new Texture5({
4072
+ this.texture = new Texture6({
3686
4073
  source: new ImageSource({
3687
4074
  resource: this.canvas,
3688
4075
  addressModeU: "clamp-to-edge",
@@ -3716,6 +4103,7 @@ export {
3716
4103
  Canvas2 as Canvas,
3717
4104
  Circle,
3718
4105
  Container4 as Container,
4106
+ DOMContainer,
3719
4107
  DisplayObject,
3720
4108
  EVENTS2 as EVENTS,
3721
4109
  Easing,
@@ -3723,12 +4111,14 @@ export {
3723
4111
  Graphics,
3724
4112
  Howl3 as Howl,
3725
4113
  Howler,
4114
+ Mesh,
3726
4115
  NineSliceSprite,
3727
4116
  ParticlesEmitter,
3728
4117
  RadialGradient,
3729
4118
  Rect,
3730
4119
  Scene,
3731
4120
  Sprite2 as Sprite,
4121
+ Svg,
3732
4122
  Text,
3733
4123
  TilingSprite,
3734
4124
  Triangle,
@@ -3752,7 +4142,6 @@ export {
3752
4142
  mountTracker,
3753
4143
  on,
3754
4144
  registerComponent,
3755
- Svg as svg,
3756
4145
  tick,
3757
4146
  trigger,
3758
4147
  useDefineProps,