canvasengine 2.0.0-beta.37 → 2.0.0-beta.39
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-CTWPthRt.js → DebugRenderer-Rrw9FlTd.js} +2 -2
- package/dist/{DebugRenderer-CTWPthRt.js.map → DebugRenderer-Rrw9FlTd.js.map} +1 -1
- package/dist/components/Button.d.ts +50 -3
- package/dist/components/Button.d.ts.map +1 -1
- package/dist/components/Canvas.d.ts.map +1 -1
- package/dist/components/Joystick.d.ts +36 -0
- package/dist/components/Joystick.d.ts.map +1 -0
- package/dist/components/Sprite.d.ts +2 -0
- package/dist/components/Sprite.d.ts.map +1 -1
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/types/Spritesheet.d.ts +0 -118
- package/dist/components/types/Spritesheet.d.ts.map +1 -1
- package/dist/directives/Controls.d.ts +16 -7
- package/dist/directives/Controls.d.ts.map +1 -1
- package/dist/directives/GamepadControls.d.ts +3 -1
- package/dist/directives/GamepadControls.d.ts.map +1 -1
- package/dist/directives/JoystickControls.d.ts +172 -0
- package/dist/directives/JoystickControls.d.ts.map +1 -0
- package/dist/directives/index.d.ts +1 -0
- package/dist/directives/index.d.ts.map +1 -1
- package/dist/engine/reactive.d.ts.map +1 -1
- package/dist/engine/signal.d.ts.map +1 -1
- package/dist/{index-BqwprEPH.js → index-BQ99FClW.js} +6057 -5433
- package/dist/index-BQ99FClW.js.map +1 -0
- package/dist/index.global.js +7 -7
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +59 -57
- package/dist/utils/GlobalAssetLoader.d.ts +141 -0
- package/dist/utils/GlobalAssetLoader.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/components/Button.ts +168 -41
- package/src/components/Canvas.ts +3 -0
- package/src/components/Joystick.ts +361 -0
- package/src/components/Sprite.ts +82 -16
- package/src/components/index.ts +2 -1
- package/src/components/types/Spritesheet.ts +0 -118
- package/src/directives/Controls.ts +42 -8
- package/src/directives/GamepadControls.ts +40 -18
- package/src/directives/JoystickControls.ts +396 -0
- package/src/directives/index.ts +1 -0
- package/src/engine/reactive.ts +362 -242
- package/src/engine/signal.ts +8 -2
- package/src/utils/GlobalAssetLoader.ts +257 -0
- package/dist/index-BqwprEPH.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h as a } from "./index-
|
|
2
|
-
import { A as r,
|
|
1
|
+
import { h as a } from "./index-BQ99FClW.js";
|
|
2
|
+
import { A as r, Y as o, Z as n, q as l, v as c, r as p, C as S, d as u, W as m, X as g, ak as d, f as b, D as C, aj as h, ah as j, w as T, j as k, G as w, t as D, c as f, I as v, _ as y, J as E, K as O, M as P, U as V, O as x, P as A, ai as B, R as G, z as H, S as M, g as J, e as N, B as R, y as q, L as F, N as I, T as K, x as U, b as z, H as L, Q, V as W, ag as X, af as Y, ad as Z, k as _, a4 as $, a2 as aa, a5 as sa, l as ea, a9 as ta, ae as ia, m as ra, n as oa, $ as na, o as la, i as ca, a0 as pa, p as Sa, aa as ua, a3 as ma, a7 as ga, a6 as da, ac as ba, a1 as Ca, s as ha, a8 as ja, ab as Ta, a as ka, u as wa } from "./index-BQ99FClW.js";
|
|
3
3
|
const e = a.Howler;
|
|
4
4
|
export {
|
|
5
5
|
r as ArraySubject,
|
|
@@ -16,62 +16,64 @@ export {
|
|
|
16
16
|
b as Drag,
|
|
17
17
|
C as Drop,
|
|
18
18
|
h as EVENTS,
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
j as Easing,
|
|
20
|
+
T as Ellipse,
|
|
21
|
+
k as Flash,
|
|
22
|
+
w as GamepadControls,
|
|
23
|
+
D as Graphics,
|
|
24
|
+
f as Howl,
|
|
25
25
|
e as Howler,
|
|
26
|
-
|
|
26
|
+
v as Input,
|
|
27
|
+
y as Joystick,
|
|
28
|
+
E as JoystickControls,
|
|
27
29
|
O as KeyboardControls,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
30
|
+
P as Mesh,
|
|
31
|
+
V as NineSliceSprite,
|
|
32
|
+
x as ObjectSubject,
|
|
33
|
+
A as ParticlesEmitter,
|
|
34
|
+
B as RadialGradient,
|
|
35
|
+
G as Rect,
|
|
36
|
+
H as Scene,
|
|
37
|
+
M as Scheduler,
|
|
38
|
+
J as Shake,
|
|
39
|
+
N as Sound,
|
|
40
|
+
R as Sprite,
|
|
41
|
+
q as Svg,
|
|
42
|
+
F as Text,
|
|
43
|
+
I as TilingSprite,
|
|
44
|
+
K as Transition,
|
|
45
|
+
U as Triangle,
|
|
46
|
+
z as Utils,
|
|
47
|
+
L as Video,
|
|
48
|
+
Q as Viewport,
|
|
49
|
+
W as ViewportFollow,
|
|
50
|
+
X as animatedSequence,
|
|
51
|
+
Y as animatedSignal,
|
|
52
|
+
Z as bootstrapCanvas,
|
|
53
|
+
_ as computed,
|
|
54
|
+
$ as cond,
|
|
55
|
+
aa as createComponent,
|
|
56
|
+
sa as currentSubscriptionsTracker,
|
|
57
|
+
ea as effect,
|
|
58
|
+
ta as h,
|
|
59
|
+
ia as isAnimatedSignal,
|
|
60
|
+
ra as isArraySubject,
|
|
61
|
+
oa as isComputed,
|
|
62
|
+
na as isElement,
|
|
63
|
+
la as isObjectSubject,
|
|
64
|
+
ca as isObservable,
|
|
65
|
+
pa as isPrimitive,
|
|
66
|
+
Sa as isSignal,
|
|
67
|
+
ua as isTrigger,
|
|
68
|
+
ma as loop,
|
|
69
|
+
ga as mount,
|
|
70
|
+
da as mountTracker,
|
|
71
|
+
ba as on,
|
|
72
|
+
Ca as registerComponent,
|
|
73
|
+
ha as signal,
|
|
74
|
+
ja as tick,
|
|
75
|
+
Ta as trigger,
|
|
76
|
+
ka as useDefineProps,
|
|
77
|
+
wa as useProps
|
|
76
78
|
};
|
|
77
79
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Asset Loader
|
|
3
|
+
*
|
|
4
|
+
* Tracks the loading progress of all assets (images, spritesheets, etc.) across all sprites in a component tree.
|
|
5
|
+
* This allows components to know when all assets are loaded, useful for displaying loaders or progress bars.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const loader = new GlobalAssetLoader();
|
|
10
|
+
*
|
|
11
|
+
* loader.onProgress((progress) => {
|
|
12
|
+
* console.log(`Loading: ${(progress * 100).toFixed(0)}%`);
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* loader.onComplete(() => {
|
|
16
|
+
* console.log('All assets loaded!');
|
|
17
|
+
* });
|
|
18
|
+
*
|
|
19
|
+
* // Register assets as they start loading
|
|
20
|
+
* const assetId = loader.registerAsset('path/to/image.png');
|
|
21
|
+
*
|
|
22
|
+
* // Update progress
|
|
23
|
+
* loader.updateProgress(assetId, 0.5);
|
|
24
|
+
*
|
|
25
|
+
* // Mark as complete
|
|
26
|
+
* loader.completeAsset(assetId);
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class GlobalAssetLoader {
|
|
30
|
+
private assets;
|
|
31
|
+
private onProgressCallbacks;
|
|
32
|
+
private onCompleteCallbacks;
|
|
33
|
+
private assetCounter;
|
|
34
|
+
private isComplete;
|
|
35
|
+
/**
|
|
36
|
+
* Registers a new asset to track
|
|
37
|
+
*
|
|
38
|
+
* @param assetPath - The path or identifier of the asset being loaded
|
|
39
|
+
* @returns A unique ID for this asset that should be used for progress updates
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const assetId = loader.registerAsset('path/to/image.png');
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
registerAsset(assetPath: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Updates the progress of a specific asset
|
|
49
|
+
*
|
|
50
|
+
* @param assetId - The ID returned by registerAsset
|
|
51
|
+
* @param progress - Progress value between 0 and 1
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```typescript
|
|
55
|
+
* loader.updateProgress(assetId, 0.5); // 50% loaded
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
updateProgress(assetId: string, progress: number): void;
|
|
59
|
+
/**
|
|
60
|
+
* Marks an asset as completely loaded
|
|
61
|
+
*
|
|
62
|
+
* @param assetId - The ID returned by registerAsset
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* loader.completeAsset(assetId);
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
completeAsset(assetId: string): void;
|
|
70
|
+
/**
|
|
71
|
+
* Removes an asset from tracking (useful for cleanup)
|
|
72
|
+
*
|
|
73
|
+
* @param assetId - The ID returned by registerAsset
|
|
74
|
+
*/
|
|
75
|
+
removeAsset(assetId: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Registers a callback that will be called whenever the global progress changes
|
|
78
|
+
*
|
|
79
|
+
* @param callback - Function that receives the global progress (0-1)
|
|
80
|
+
* @returns A function to unregister the callback
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const unsubscribe = loader.onProgress((progress) => {
|
|
85
|
+
* console.log(`Loading: ${(progress * 100).toFixed(0)}%`);
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* // Later, to unsubscribe:
|
|
89
|
+
* unsubscribe();
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
onProgress(callback: (progress: number) => void): () => void;
|
|
93
|
+
/**
|
|
94
|
+
* Registers a callback that will be called when all assets are loaded
|
|
95
|
+
*
|
|
96
|
+
* @param callback - Function to call when all assets are complete
|
|
97
|
+
* @returns A function to unregister the callback
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const unsubscribe = loader.onComplete(() => {
|
|
102
|
+
* console.log('All assets loaded!');
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* // Later, to unsubscribe:
|
|
106
|
+
* unsubscribe();
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
onComplete(callback: () => void): () => void;
|
|
110
|
+
/**
|
|
111
|
+
* Gets the current global progress (0-1)
|
|
112
|
+
*
|
|
113
|
+
* @returns Progress value between 0 and 1
|
|
114
|
+
*/
|
|
115
|
+
getGlobalProgress(): number;
|
|
116
|
+
/**
|
|
117
|
+
* Gets the number of assets currently being tracked
|
|
118
|
+
*
|
|
119
|
+
* @returns Number of registered assets
|
|
120
|
+
*/
|
|
121
|
+
getAssetCount(): number;
|
|
122
|
+
/**
|
|
123
|
+
* Gets the number of completed assets
|
|
124
|
+
*
|
|
125
|
+
* @returns Number of completed assets
|
|
126
|
+
*/
|
|
127
|
+
getCompletedCount(): number;
|
|
128
|
+
/**
|
|
129
|
+
* Checks if all assets are loaded and triggers onComplete callbacks
|
|
130
|
+
*/
|
|
131
|
+
private checkCompletion;
|
|
132
|
+
/**
|
|
133
|
+
* Updates global progress and notifies all progress callbacks
|
|
134
|
+
*/
|
|
135
|
+
private updateGlobalProgress;
|
|
136
|
+
/**
|
|
137
|
+
* Resets the loader, clearing all assets and callbacks
|
|
138
|
+
*/
|
|
139
|
+
reset(): void;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=GlobalAssetLoader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GlobalAssetLoader.d.ts","sourceRoot":"","sources":["../../src/utils/GlobalAssetLoader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAoE;IAClF,OAAO,CAAC,mBAAmB,CAA8C;IACzE,OAAO,CAAC,mBAAmB,CAA8B;IACzD,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,UAAU,CAAkB;IAEpC;;;;;;;;;;OAUG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAQxC;;;;;;;;;;OAUG;IACH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAWvD;;;;;;;;;OASG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAapC;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKlC;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAe5D;;;;;;;;;;;;;;;OAeG;IACH,UAAU,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAa5C;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAa3B;;;;OAIG;IACH,aAAa,IAAI,MAAM;IAIvB;;;;OAIG;IACH,iBAAiB,IAAI,MAAM;IAQ3B;;OAEG;IACH,OAAO,CAAC,eAAe;IAiBvB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAa5B;;OAEG;IACH,KAAK,IAAI,IAAI;CAOd"}
|
package/package.json
CHANGED
package/src/components/Button.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { effect, signal, computed } from "@signe/reactive";
|
|
1
|
+
import { effect, signal, computed, isSignal } from "@signe/reactive";
|
|
2
2
|
import { FederatedPointerEvent } from "pixi.js";
|
|
3
3
|
import { h } from "../engine/signal";
|
|
4
4
|
import { useDefineProps } from "../hooks/useProps";
|
|
5
5
|
import { Container } from "./Container";
|
|
6
|
-
import { Rect } from "./Graphic";
|
|
6
|
+
import { Rect, Circle, Ellipse } from "./Graphic";
|
|
7
7
|
import { Text } from "./Text";
|
|
8
|
+
import { ControlsDirective } from "../directives/Controls";
|
|
9
|
+
import { JoystickControls } from "../directives/JoystickControls";
|
|
10
|
+
import { Element } from "../engine/reactive";
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Button states for visual feedback
|
|
@@ -82,6 +85,16 @@ export interface ButtonProps {
|
|
|
82
85
|
visible?: boolean;
|
|
83
86
|
/** Button cursor */
|
|
84
87
|
cursor?: string;
|
|
88
|
+
/** Controls instance to automatically apply button events to (e.g., ControlsDirective or JoystickControls) */
|
|
89
|
+
controls?: ControlsDirective | JoystickControls | any;
|
|
90
|
+
/** Name of the control to trigger with applyControl when button is clicked */
|
|
91
|
+
controlName?: string;
|
|
92
|
+
/** Shape of the button background: 'rect', 'circle', or 'ellipse' */
|
|
93
|
+
shape?: 'rect' | 'circle' | 'ellipse';
|
|
94
|
+
/** Custom background component or element (replaces default background if provided) */
|
|
95
|
+
background?: Element | any;
|
|
96
|
+
/** Custom children components for button content (takes priority over text if provided) */
|
|
97
|
+
children?: Element[];
|
|
85
98
|
}
|
|
86
99
|
|
|
87
100
|
/**
|
|
@@ -94,18 +107,52 @@ export interface ButtonProps {
|
|
|
94
107
|
* The button is built using a Container with background and text elements,
|
|
95
108
|
* providing reactive state management and event handling.
|
|
96
109
|
*
|
|
97
|
-
*
|
|
110
|
+
* ## Features
|
|
111
|
+
*
|
|
112
|
+
* - **Controls Integration**: Automatically trigger controls via `applyControl` when clicked
|
|
113
|
+
* - **Multiple Shapes**: Support for rect, circle, and ellipse shapes
|
|
114
|
+
* - **Custom Content**: Use children components for custom button content
|
|
115
|
+
* - **Custom Background**: Provide a custom background component
|
|
116
|
+
*
|
|
117
|
+
* @param props - Button configuration including text, styling, controls, shape, and event handlers
|
|
98
118
|
* @returns A reactive Button component
|
|
99
119
|
* @example
|
|
100
120
|
* ```typescript
|
|
101
121
|
* // Simple button with text and click handler
|
|
102
122
|
* const simpleButton = Button({
|
|
103
123
|
* text: "Click Me",
|
|
104
|
-
*
|
|
124
|
+
* click: () => console.log("Button clicked!"),
|
|
105
125
|
* width: 150,
|
|
106
126
|
* height: 50
|
|
107
127
|
* });
|
|
108
128
|
*
|
|
129
|
+
* // Button with controls integration
|
|
130
|
+
* const jumpButton = Button({
|
|
131
|
+
* text: "Jump",
|
|
132
|
+
* controls: controlsInstance,
|
|
133
|
+
* controlName: "jump",
|
|
134
|
+
* width: 120,
|
|
135
|
+
* height: 40
|
|
136
|
+
* });
|
|
137
|
+
*
|
|
138
|
+
* // Circular button
|
|
139
|
+
* const circleButton = Button({
|
|
140
|
+
* text: "Action",
|
|
141
|
+
* shape: "circle",
|
|
142
|
+
* width: 100,
|
|
143
|
+
* height: 100
|
|
144
|
+
* });
|
|
145
|
+
*
|
|
146
|
+
* // Button with custom content (children)
|
|
147
|
+
* const customButton = Button({
|
|
148
|
+
* shape: "circle",
|
|
149
|
+
* width: 80,
|
|
150
|
+
* height: 80,
|
|
151
|
+
* children: [
|
|
152
|
+
* h(Sprite, { image: "icon.png", width: 50, height: 50 })
|
|
153
|
+
* ]
|
|
154
|
+
* });
|
|
155
|
+
*
|
|
109
156
|
* // Styled button with custom colors
|
|
110
157
|
* const styledButton = Button({
|
|
111
158
|
* text: "Styled Button",
|
|
@@ -149,7 +196,7 @@ export function Button(props: ButtonProps) {
|
|
|
149
196
|
|
|
150
197
|
// Define reactive props with defaults
|
|
151
198
|
const defineProps = useDefineProps(props);
|
|
152
|
-
const { text, disabled, width, height, style } = defineProps({
|
|
199
|
+
const { text, disabled, width, height, style, shape, controlName } = defineProps({
|
|
153
200
|
text: {
|
|
154
201
|
type: String,
|
|
155
202
|
default: ""
|
|
@@ -169,9 +216,26 @@ export function Button(props: ButtonProps) {
|
|
|
169
216
|
style: {
|
|
170
217
|
type: Object,
|
|
171
218
|
default: () => ({})
|
|
219
|
+
},
|
|
220
|
+
shape: {
|
|
221
|
+
type: String,
|
|
222
|
+
default: "rect"
|
|
223
|
+
},
|
|
224
|
+
controlName: {
|
|
225
|
+
type: String,
|
|
226
|
+
default: undefined
|
|
172
227
|
}
|
|
173
228
|
});
|
|
174
229
|
|
|
230
|
+
// Helper function to get controls instance (handles signals like Joystick)
|
|
231
|
+
const getControls = () => {
|
|
232
|
+
if (!props.controls) return null;
|
|
233
|
+
if (isSignal(props.controls)) {
|
|
234
|
+
return props.controls();
|
|
235
|
+
}
|
|
236
|
+
return props.controls;
|
|
237
|
+
};
|
|
238
|
+
|
|
175
239
|
// Update button state based on disabled and interaction states
|
|
176
240
|
effect(() => {
|
|
177
241
|
const isDisabled = disabled();
|
|
@@ -202,25 +266,119 @@ export function Button(props: ButtonProps) {
|
|
|
202
266
|
isPressed.set(false);
|
|
203
267
|
props.hoverLeave?.(event);
|
|
204
268
|
},
|
|
205
|
-
pointerdown: (event: FederatedPointerEvent) => {
|
|
269
|
+
pointerdown: async (event: FederatedPointerEvent) => {
|
|
206
270
|
if (!disabled()) {
|
|
207
271
|
isPressed.set(true);
|
|
208
272
|
props.pressDown?.(event);
|
|
273
|
+
|
|
274
|
+
// Apply control if controls and controlName are provided
|
|
275
|
+
const controls = getControls();
|
|
276
|
+
const name = controlName();
|
|
277
|
+
if (controls && name && controls.applyControl) {
|
|
278
|
+
await controls.applyControl(name, true);
|
|
279
|
+
}
|
|
209
280
|
}
|
|
210
281
|
},
|
|
211
|
-
pointerup: (event: FederatedPointerEvent) => {
|
|
282
|
+
pointerup: async (event: FederatedPointerEvent) => {
|
|
212
283
|
if (!disabled() && isPressed()) {
|
|
213
284
|
isPressed.set(false);
|
|
214
285
|
props.pressUp?.(event);
|
|
286
|
+
|
|
287
|
+
// Apply control release if controls and controlName are provided
|
|
288
|
+
const controls = getControls();
|
|
289
|
+
const name = controlName();
|
|
290
|
+
if (controls && name && controls.applyControl) {
|
|
291
|
+
await controls.applyControl(name, false);
|
|
292
|
+
}
|
|
215
293
|
}
|
|
216
294
|
},
|
|
217
|
-
pointertap: (event: FederatedPointerEvent) => {
|
|
295
|
+
pointertap: async (event: FederatedPointerEvent) => {
|
|
218
296
|
if (!disabled()) {
|
|
219
297
|
props.click?.(event);
|
|
298
|
+
|
|
299
|
+
// Apply control if controls and controlName are provided (press and release)
|
|
300
|
+
const controls = getControls();
|
|
301
|
+
const name = controlName();
|
|
302
|
+
if (controls && name && controls.applyControl) {
|
|
303
|
+
await controls.applyControl(name);
|
|
304
|
+
}
|
|
220
305
|
}
|
|
221
306
|
}
|
|
222
307
|
};
|
|
223
308
|
|
|
309
|
+
// Generate background element
|
|
310
|
+
const getBackgroundElement = () => {
|
|
311
|
+
// If custom background is provided, use it
|
|
312
|
+
if (props.background) {
|
|
313
|
+
return props.background;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Otherwise, use shape-based background
|
|
317
|
+
const currentShape = shape();
|
|
318
|
+
const bgColor = computed(() => {
|
|
319
|
+
const currentStyle = style();
|
|
320
|
+
const backgroundColor = currentStyle.backgroundColor || {
|
|
321
|
+
[ButtonState.Normal]: "#007bff",
|
|
322
|
+
[ButtonState.Hover]: "#0056b3",
|
|
323
|
+
[ButtonState.Pressed]: "#004085",
|
|
324
|
+
[ButtonState.Disabled]: "#6c757d"
|
|
325
|
+
};
|
|
326
|
+
const state = currentState();
|
|
327
|
+
return backgroundColor[state] || backgroundColor[ButtonState.Normal];
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
if (currentShape === 'circle') {
|
|
331
|
+
// For circle, use the smaller dimension as radius
|
|
332
|
+
const radius = computed(() => Math.min(width(), height()) / 2);
|
|
333
|
+
return h(Circle, {
|
|
334
|
+
radius: radius,
|
|
335
|
+
x: computed(() => width() / 2),
|
|
336
|
+
y: computed(() => height() / 2),
|
|
337
|
+
color: bgColor
|
|
338
|
+
});
|
|
339
|
+
} else if (currentShape === 'ellipse') {
|
|
340
|
+
return h(Ellipse, {
|
|
341
|
+
width: width,
|
|
342
|
+
height: height,
|
|
343
|
+
color: bgColor
|
|
344
|
+
});
|
|
345
|
+
} else {
|
|
346
|
+
// Default: rect
|
|
347
|
+
return h(Rect, {
|
|
348
|
+
width: width,
|
|
349
|
+
height: height,
|
|
350
|
+
color: bgColor
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
// Generate content element(s)
|
|
356
|
+
const getContentElements = () => {
|
|
357
|
+
// If children are provided, use them (priority over text)
|
|
358
|
+
if (props.children && props.children.length > 0) {
|
|
359
|
+
return props.children;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Otherwise, use text
|
|
363
|
+
return [
|
|
364
|
+
h(Text, {
|
|
365
|
+
text: text,
|
|
366
|
+
x: computed(() => width() / 2),
|
|
367
|
+
y: computed(() => height() / 2),
|
|
368
|
+
anchor: { x: 0.5, y: 0.5 },
|
|
369
|
+
style: computed(() => {
|
|
370
|
+
const currentStyle = style();
|
|
371
|
+
const textStyle = currentStyle.text || {};
|
|
372
|
+
return {
|
|
373
|
+
fontSize: textStyle.fontSize || 16,
|
|
374
|
+
fontFamily: textStyle.fontFamily || "Arial",
|
|
375
|
+
fill: textStyle.color || "#ffffff"
|
|
376
|
+
};
|
|
377
|
+
})()
|
|
378
|
+
})
|
|
379
|
+
];
|
|
380
|
+
};
|
|
381
|
+
|
|
224
382
|
// Return Container with h() children
|
|
225
383
|
return h(Container, {
|
|
226
384
|
x: props.x,
|
|
@@ -232,38 +390,7 @@ export function Button(props: ButtonProps) {
|
|
|
232
390
|
cursor: props.cursor || "pointer",
|
|
233
391
|
...eventHandlers
|
|
234
392
|
}, [
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
width: width,
|
|
238
|
-
height: height,
|
|
239
|
-
color: computed(() => {
|
|
240
|
-
const currentStyle = style();
|
|
241
|
-
const backgroundColor = currentStyle.backgroundColor || {
|
|
242
|
-
[ButtonState.Normal]: "#007bff",
|
|
243
|
-
[ButtonState.Hover]: "#0056b3",
|
|
244
|
-
[ButtonState.Pressed]: "#004085",
|
|
245
|
-
[ButtonState.Disabled]: "#6c757d"
|
|
246
|
-
};
|
|
247
|
-
const state = currentState();
|
|
248
|
-
return backgroundColor[state] || backgroundColor[ButtonState.Normal];
|
|
249
|
-
})
|
|
250
|
-
}),
|
|
251
|
-
|
|
252
|
-
// Text element
|
|
253
|
-
h(Text, {
|
|
254
|
-
text: text,
|
|
255
|
-
x: computed(() => width() / 2),
|
|
256
|
-
y: computed(() => height() / 2),
|
|
257
|
-
anchor: { x: 0.5, y: 0.5 },
|
|
258
|
-
style: computed(() => {
|
|
259
|
-
const currentStyle = style();
|
|
260
|
-
const textStyle = currentStyle.text || {};
|
|
261
|
-
return {
|
|
262
|
-
fontSize: textStyle.fontSize || 16,
|
|
263
|
-
fontFamily: textStyle.fontFamily || "Arial",
|
|
264
|
-
fill: textStyle.color || "#ffffff"
|
|
265
|
-
};
|
|
266
|
-
})()
|
|
267
|
-
})
|
|
393
|
+
getBackgroundElement(),
|
|
394
|
+
...getContentElements()
|
|
268
395
|
]);
|
|
269
396
|
}
|
package/src/components/Canvas.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { ComponentFunction } from "../engine/signal";
|
|
|
12
12
|
import { SignalOrPrimitive } from "./types";
|
|
13
13
|
import { Size } from "./types/DisplayObject";
|
|
14
14
|
import { Scheduler, Tick } from "../directives/Scheduler";
|
|
15
|
+
import { GlobalAssetLoader } from "../utils/GlobalAssetLoader";
|
|
15
16
|
|
|
16
17
|
interface CanvasElement extends Element<ComponentInstance> {
|
|
17
18
|
render: (rootElement: HTMLElement, app?: Application) => void;
|
|
@@ -49,11 +50,13 @@ export const Canvas: ComponentFunction<CanvasProps> = async (props = {}) => {
|
|
|
49
50
|
});
|
|
50
51
|
|
|
51
52
|
props.isRoot = true;
|
|
53
|
+
const globalLoader = new GlobalAssetLoader();
|
|
52
54
|
const options: CanvasProps = {
|
|
53
55
|
...props,
|
|
54
56
|
context: {
|
|
55
57
|
canvasSize,
|
|
56
58
|
app: signal(null),
|
|
59
|
+
globalLoader,
|
|
57
60
|
},
|
|
58
61
|
width: width?.(),
|
|
59
62
|
height: height?.(),
|