canvasengine 2.0.0-beta.3 → 2.0.0-beta.5

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
@@ -1,6 +1,11 @@
1
+ var __defProp = Object.defineProperty;
1
2
  var __typeError = (msg) => {
2
3
  throw TypeError(msg);
3
4
  };
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
4
9
  var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
10
  var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
11
  var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
@@ -24,6 +29,22 @@ function applyDirective(element, directiveName) {
24
29
  }
25
30
 
26
31
  // src/engine/utils.ts
32
+ var utils_exports = {};
33
+ __export(utils_exports, {
34
+ arrayEquals: () => arrayEquals,
35
+ calculateDistance: () => calculateDistance,
36
+ error: () => error,
37
+ fps2ms: () => fps2ms,
38
+ get: () => get,
39
+ isBrowser: () => isBrowser,
40
+ isFunction: () => isFunction,
41
+ isObject: () => isObject,
42
+ isPromise: () => isPromise,
43
+ log: () => log,
44
+ preciseNow: () => preciseNow,
45
+ set: () => set,
46
+ setObservablePoint: () => setObservablePoint
47
+ });
27
48
  function isBrowser() {
28
49
  return typeof window !== "undefined";
29
50
  }
@@ -92,7 +113,7 @@ function set(obj, path, value, onlyPlainObject = false) {
92
113
  for (let i = 0; i < len - 1; i++) {
93
114
  let segment = path[i];
94
115
  let nextSegment = path[i + 1];
95
- let isNextNumeric = !isNaN(nextSegment) && isFinite(nextSegment);
116
+ let isNextNumeric = !isNaN(Number(nextSegment)) && isFinite(Number(nextSegment));
96
117
  if (!current[segment] || typeof current[segment] !== "object") {
97
118
  current[segment] = isNextNumeric && !onlyPlainObject ? [] : {};
98
119
  }
@@ -101,6 +122,20 @@ function set(obj, path, value, onlyPlainObject = false) {
101
122
  current[path[len - 1]] = value;
102
123
  return obj;
103
124
  }
125
+ function get(obj, path) {
126
+ const keys = path.split(".");
127
+ let current = obj;
128
+ for (let key of keys) {
129
+ if (current[key] === void 0) {
130
+ return void 0;
131
+ }
132
+ current = current[key];
133
+ }
134
+ return current;
135
+ }
136
+ function log(text) {
137
+ console.log(text);
138
+ }
104
139
  function error(text) {
105
140
  console.error(text);
106
141
  }
@@ -1174,8 +1209,20 @@ function createComponent(tag, props) {
1174
1209
  recursiveProps(props);
1175
1210
  }
1176
1211
  instance.onInit?.(element.props);
1177
- instance.onUpdate?.(element.props);
1178
- const onMount = (parent, element2, index) => {
1212
+ const elementsListen = new Subject();
1213
+ if (props?.isRoot) {
1214
+ element.allElements = elementsListen;
1215
+ element.props.context.rootElement = element;
1216
+ element.componentInstance.onMount?.(element);
1217
+ propagateContext(element);
1218
+ }
1219
+ if (props) {
1220
+ for (let key in props) {
1221
+ const directive = applyDirective(element, key);
1222
+ if (directive) element.directives[key] = directive;
1223
+ }
1224
+ }
1225
+ function onMount(parent, element2, index) {
1179
1226
  element2.props.context = parent.props.context;
1180
1227
  element2.parent = parent;
1181
1228
  element2.componentInstance.onMount?.(element2, index);
@@ -1185,62 +1232,76 @@ function createComponent(tag, props) {
1185
1232
  element2.effectMounts.forEach((fn) => {
1186
1233
  element2.effectUnmounts.push(fn(element2));
1187
1234
  });
1188
- };
1189
- const elementsListen = new Subject();
1190
- if (props?.isRoot) {
1191
- const propagateContext = async (element2) => {
1192
- if (!element2.props.children) {
1193
- return;
1235
+ }
1236
+ ;
1237
+ async function propagateContext(element2) {
1238
+ if (element2.props.attach) {
1239
+ const isReactiveAttach = isSignal2(element2.propObservables?.attach);
1240
+ if (!isReactiveAttach) {
1241
+ element2.props.children.push(element2.props.attach);
1242
+ } else {
1243
+ await new Promise((resolve) => {
1244
+ let lastElement = null;
1245
+ element2.propSubscriptions.push(element2.propObservables.attach.observable.subscribe(async (args) => {
1246
+ const value = args?.value ?? args;
1247
+ if (!value) {
1248
+ throw new Error(`attach in ${element2.tag} is undefined or null, add a component`);
1249
+ }
1250
+ if (lastElement) {
1251
+ destroyElement(lastElement);
1252
+ }
1253
+ lastElement = value;
1254
+ await createElement(element2, value);
1255
+ resolve(void 0);
1256
+ }));
1257
+ });
1194
1258
  }
1195
- for (let child of element2.props.children) {
1196
- if (!child) continue;
1197
- if (isPromise(child)) {
1198
- child = await child;
1199
- }
1200
- if (child instanceof Observable) {
1201
- child.subscribe(
1202
- ({
1203
- elements: comp,
1204
- prev
1205
- }) => {
1206
- const components2 = comp.filter((c) => c !== null);
1207
- if (prev) {
1208
- components2.forEach((c) => {
1209
- const index = element2.props.children.indexOf(prev.props.key);
1210
- onMount(element2, c, index + 1);
1211
- propagateContext(c);
1212
- });
1213
- return;
1214
- }
1215
- components2.forEach((component) => {
1216
- if (!Array.isArray(component)) {
1217
- onMount(element2, component);
1218
- propagateContext(component);
1219
- } else {
1220
- component.forEach((comp2) => {
1221
- onMount(element2, comp2);
1222
- propagateContext(comp2);
1223
- });
1224
- }
1259
+ }
1260
+ if (!element2.props.children) {
1261
+ return;
1262
+ }
1263
+ for (let child of element2.props.children) {
1264
+ if (!child) continue;
1265
+ await createElement(element2, child);
1266
+ }
1267
+ }
1268
+ ;
1269
+ async function createElement(parent, child) {
1270
+ if (isPromise(child)) {
1271
+ child = await child;
1272
+ }
1273
+ if (child instanceof Observable) {
1274
+ child.subscribe(
1275
+ ({
1276
+ elements: comp,
1277
+ prev
1278
+ }) => {
1279
+ const components2 = comp.filter((c) => c !== null);
1280
+ if (prev) {
1281
+ components2.forEach((c) => {
1282
+ const index = parent.props.children.indexOf(prev.props.key);
1283
+ onMount(parent, c, index + 1);
1284
+ propagateContext(c);
1285
+ });
1286
+ return;
1287
+ }
1288
+ components2.forEach((component) => {
1289
+ if (!Array.isArray(component)) {
1290
+ onMount(parent, component);
1291
+ propagateContext(component);
1292
+ } else {
1293
+ component.forEach((comp2) => {
1294
+ onMount(parent, comp2);
1295
+ propagateContext(comp2);
1225
1296
  });
1226
- elementsListen.next(void 0);
1227
1297
  }
1228
- );
1229
- } else {
1230
- onMount(element2, child);
1231
- await propagateContext(child);
1298
+ });
1299
+ elementsListen.next(void 0);
1232
1300
  }
1233
- }
1234
- };
1235
- element.allElements = elementsListen;
1236
- element.props.context.rootElement = element;
1237
- element.componentInstance.onMount?.(element);
1238
- propagateContext(element);
1239
- }
1240
- if (props) {
1241
- for (let key in props) {
1242
- const directive = applyDirective(element, key);
1243
- if (directive) element.directives[key] = directive;
1301
+ );
1302
+ } else {
1303
+ onMount(parent, child);
1304
+ await propagateContext(child);
1244
1305
  }
1245
1306
  }
1246
1307
  return element;
@@ -2117,8 +2178,8 @@ import {
2117
2178
  // src/engine/animation.ts
2118
2179
  import { effect as effect6, signal as signal4 } from "@signe/reactive";
2119
2180
  import { animate as animatePopmotion } from "popmotion";
2120
- function isAnimatedSignal(signal6) {
2121
- return signal6.animatedState !== void 0;
2181
+ function isAnimatedSignal(signal7) {
2182
+ return signal7.animatedState !== void 0;
2122
2183
  }
2123
2184
  function animatedSignal(initialValue, options = {}) {
2124
2185
  const state = {
@@ -2178,7 +2239,7 @@ function animatedSignal(initialValue, options = {}) {
2178
2239
  }
2179
2240
 
2180
2241
  // src/components/Sprite.ts
2181
- var log = console.log;
2242
+ var log2 = console.log;
2182
2243
  var CanvasSprite = class extends DisplayObject(PixiSprite) {
2183
2244
  constructor() {
2184
2245
  super(...arguments);
@@ -2205,12 +2266,12 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2205
2266
  const rectX = j * spriteWidth + offsetX;
2206
2267
  const rectY = i * spriteHeight + offsetY;
2207
2268
  if (rectY > height) {
2208
- throw log(
2269
+ throw log2(
2209
2270
  `Warning, there is a problem with the height of the "${this.id}" spritesheet. When cutting into frames, the frame exceeds the height of the image.`
2210
2271
  );
2211
2272
  }
2212
2273
  if (rectX > width) {
2213
- throw log(
2274
+ throw log2(
2214
2275
  `Warning, there is a problem with the width of the "${this.id}" spritesheet. When cutting into frames, the frame exceeds the width of the image.`
2215
2276
  );
2216
2277
  }
@@ -2323,6 +2384,21 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2323
2384
  }
2324
2385
  async onUpdate(props) {
2325
2386
  super.onUpdate(props);
2387
+ const setTexture = async (image) => {
2388
+ const onProgress = this.fullProps.loader?.onProgress;
2389
+ const texture = await Assets.load(image, (progress) => {
2390
+ if (onProgress) onProgress(progress);
2391
+ if (progress == 1) {
2392
+ const onComplete = this.fullProps.loader?.onComplete;
2393
+ if (onComplete) {
2394
+ setTimeout(() => {
2395
+ onComplete(texture);
2396
+ });
2397
+ }
2398
+ }
2399
+ });
2400
+ return texture;
2401
+ };
2326
2402
  const sheet = props.sheet;
2327
2403
  if (sheet?.params) this.sheetParams = sheet?.params;
2328
2404
  if (sheet?.playing && this.isMounted) {
@@ -2332,13 +2408,13 @@ var CanvasSprite = class extends DisplayObject(PixiSprite) {
2332
2408
  if (props.hitbox) this.hitbox = props.hitbox;
2333
2409
  if (props.scaleMode) this.baseTexture.scaleMode = props.scaleMode;
2334
2410
  else if (props.image && this.fullProps.rectangle === void 0) {
2335
- this.texture = await Assets.load(this.fullProps.image);
2411
+ this.texture = await setTexture(this.fullProps.image);
2336
2412
  } else if (props.texture) {
2337
2413
  this.texture = props.texture;
2338
2414
  }
2339
2415
  if (props.rectangle !== void 0) {
2340
2416
  const { x, y, width, height } = props.rectangle?.value ?? props.rectangle;
2341
- const texture = await Assets.load(this.fullProps.image);
2417
+ const texture = await setTexture(this.fullProps.image);
2342
2418
  this.texture = new Texture2({
2343
2419
  source: texture.source,
2344
2420
  frame: new Rectangle2(x, y, width, height)
@@ -2479,23 +2555,128 @@ var Sprite2 = (props) => {
2479
2555
  return createComponent("Sprite", props);
2480
2556
  };
2481
2557
 
2558
+ // src/components/Video.ts
2559
+ import { effect as effect8, signal as signal5 } from "@signe/reactive";
2560
+ function Video(props) {
2561
+ const eventsMap = {
2562
+ audioprocess: null,
2563
+ canplay: null,
2564
+ canplaythrough: null,
2565
+ complete: null,
2566
+ durationchange: null,
2567
+ emptied: null,
2568
+ ended: null,
2569
+ loadeddata: null,
2570
+ loadedmetadata: null,
2571
+ pause: null,
2572
+ play: null,
2573
+ playing: null,
2574
+ progress: null,
2575
+ ratechange: null,
2576
+ seeked: null,
2577
+ seeking: null,
2578
+ stalled: null,
2579
+ suspend: null,
2580
+ timeupdate: null,
2581
+ volumechange: null,
2582
+ waiting: null
2583
+ };
2584
+ const video = signal5(null);
2585
+ const defineProps = useDefineProps(props);
2586
+ const { play, loop: loop2, muted } = defineProps({
2587
+ play: {
2588
+ type: Boolean,
2589
+ default: true
2590
+ },
2591
+ loop: {
2592
+ type: Boolean,
2593
+ default: false
2594
+ },
2595
+ muted: {
2596
+ type: Boolean,
2597
+ default: false
2598
+ }
2599
+ });
2600
+ effect8(() => {
2601
+ const _video = video();
2602
+ const state = play();
2603
+ if (_video && state !== void 0) {
2604
+ if (state) {
2605
+ _video.play();
2606
+ } else {
2607
+ _video.pause();
2608
+ }
2609
+ }
2610
+ if (_video && loop2()) {
2611
+ _video.loop = loop2();
2612
+ }
2613
+ if (_video && muted()) {
2614
+ _video.muted = muted();
2615
+ }
2616
+ });
2617
+ mount(() => {
2618
+ return () => {
2619
+ for (let event in eventsMap) {
2620
+ if (eventsMap[event]) {
2621
+ video().removeEventListener(event, eventsMap[event]);
2622
+ }
2623
+ }
2624
+ };
2625
+ });
2626
+ return h(Sprite2, {
2627
+ ...props,
2628
+ image: props.source,
2629
+ loader: {
2630
+ onComplete: (texture) => {
2631
+ const source = texture.source.resource;
2632
+ video.set(source);
2633
+ if (props?.loader?.onComplete) {
2634
+ props.loader.onComplete(texture);
2635
+ }
2636
+ for (let event in eventsMap) {
2637
+ if (props[event]) {
2638
+ const cb = (ev) => {
2639
+ props[event](ev);
2640
+ };
2641
+ eventsMap[event] = cb;
2642
+ source.addEventListener(event, cb);
2643
+ }
2644
+ }
2645
+ }
2646
+ }
2647
+ });
2648
+ }
2649
+
2482
2650
  // src/components/Text.ts
2483
2651
  import { Text as PixiText } from "pixi.js";
2484
2652
 
2485
2653
  // src/engine/trigger.ts
2486
- import { effect as effect8, signal as signal5 } from "@signe/reactive";
2654
+ import { effect as effect9, signal as signal6 } from "@signe/reactive";
2487
2655
  function isTrigger(arg) {
2488
2656
  return arg?.start && arg?.listen;
2489
2657
  }
2490
- function trigger(config) {
2491
- const _signal = signal5(0);
2658
+ function trigger(globalConfig) {
2659
+ const _signal = signal6({
2660
+ config: globalConfig,
2661
+ value: 0,
2662
+ resolve: (value) => void 0
2663
+ });
2492
2664
  return {
2493
- start: () => {
2494
- _signal.set(Math.random());
2665
+ start: (config) => {
2666
+ return new Promise((resolve) => {
2667
+ _signal.set({
2668
+ config: {
2669
+ ...globalConfig,
2670
+ ...config
2671
+ },
2672
+ resolve,
2673
+ value: Math.random()
2674
+ });
2675
+ });
2495
2676
  },
2496
2677
  listen: () => {
2497
2678
  return {
2498
- config,
2679
+ config: globalConfig,
2499
2680
  seed: _signal()
2500
2681
  };
2501
2682
  }
@@ -2505,9 +2686,14 @@ function on(triggerSignal, callback) {
2505
2686
  if (!isTrigger(triggerSignal)) {
2506
2687
  throw new Error("In 'on(arg)' must have a trigger signal type");
2507
2688
  }
2508
- effect8(() => {
2689
+ effect9(() => {
2509
2690
  const result = triggerSignal.listen();
2510
- if (result?.seed) callback(result.config);
2691
+ if (result?.seed.value) {
2692
+ const ret = callback(result?.seed.config);
2693
+ if (ret && typeof ret.then === "function") {
2694
+ ret.then(result?.seed.resolve);
2695
+ }
2696
+ }
2511
2697
  });
2512
2698
  }
2513
2699
 
@@ -2647,7 +2833,7 @@ function TilingSprite(props) {
2647
2833
 
2648
2834
  // src/components/Viewport.ts
2649
2835
  import { Viewport as PixiViewport } from "pixi-viewport";
2650
- import { effect as effect9 } from "@signe/reactive";
2836
+ import { effect as effect10 } from "@signe/reactive";
2651
2837
  var EVENTS3 = [
2652
2838
  "bounce-x-end",
2653
2839
  "bounce-x-start",
@@ -2698,7 +2884,7 @@ var CanvasViewport = class extends DisplayObject(PixiViewport) {
2698
2884
  super.onMount(element);
2699
2885
  const { tick: tick2, renderer, canvasSize } = element.props.context;
2700
2886
  let isDragging = false;
2701
- effect9(() => {
2887
+ effect10(() => {
2702
2888
  this.screenWidth = canvasSize().width;
2703
2889
  this.screenHeight = canvasSize().height;
2704
2890
  });
@@ -2838,6 +3024,16 @@ var Easing = {
2838
3024
  // src/utils/RadialGradient.ts
2839
3025
  import { Texture as Texture5, ImageSource, DOMAdapter, Matrix } from "pixi.js";
2840
3026
  var RadialGradient = class {
3027
+ /**
3028
+ * Creates a new RadialGradient instance
3029
+ * @param x0 - The x-coordinate of the starting circle
3030
+ * @param y0 - The y-coordinate of the starting circle
3031
+ * @param x1 - The x-coordinate of the ending circle
3032
+ * @param y1 - The y-coordinate of the ending circle
3033
+ * @param x2 - The x-coordinate for gradient transformation
3034
+ * @param y2 - The y-coordinate for gradient transformation
3035
+ * @param focalPoint - The focal point of the gradient (0-1), defaults to 0
3036
+ */
2841
3037
  constructor(x0, y0, x1, y1, x2, y2, focalPoint = 0) {
2842
3038
  this.x0 = x0;
2843
3039
  this.y0 = y0;
@@ -2866,11 +3062,22 @@ var RadialGradient = class {
2866
3062
  );
2867
3063
  }
2868
3064
  }
3065
+ /**
3066
+ * Adds a color stop to the gradient
3067
+ * @param offset - The position of the color stop (0-1)
3068
+ * @param color - The color value (any valid CSS color string)
3069
+ */
2869
3070
  addColorStop(offset, color) {
2870
3071
  if (this.gradient) {
2871
3072
  this.gradient.addColorStop(offset, color);
2872
3073
  }
2873
3074
  }
3075
+ /**
3076
+ * Renders the gradient and returns the texture with its transformation matrix
3077
+ * @param options - Render options
3078
+ * @param options.translate - Optional translation coordinates
3079
+ * @returns Object containing the texture and transformation matrix
3080
+ */
2874
3081
  render({ translate } = {}) {
2875
3082
  const { x0, y0, x1, y1, x2, y2, focalPoint } = this;
2876
3083
  const defaultSize = this.size;
@@ -2925,6 +3132,8 @@ export {
2925
3132
  Text,
2926
3133
  TilingSprite,
2927
3134
  Triangle,
3135
+ utils_exports as Utils,
3136
+ Video,
2928
3137
  Viewport,
2929
3138
  animatedSignal,
2930
3139
  bootstrapCanvas,