canvasengine 2.0.0-beta.34 → 2.0.0-beta.35
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-BYa_lwD-.js → DebugRenderer-DMqhoMfE.js} +2 -2
- package/dist/{DebugRenderer-BYa_lwD-.js.map → DebugRenderer-DMqhoMfE.js.map} +1 -1
- package/dist/components/Sprite.d.ts +44 -0
- package/dist/components/Sprite.d.ts.map +1 -1
- package/dist/directives/Controls.d.ts +102 -0
- package/dist/directives/Controls.d.ts.map +1 -0
- package/dist/directives/ControlsBase.d.ts +198 -0
- package/dist/directives/ControlsBase.d.ts.map +1 -0
- package/dist/directives/GamepadControls.d.ts +223 -0
- package/dist/directives/GamepadControls.d.ts.map +1 -0
- package/dist/directives/KeyboardControls.d.ts +55 -366
- package/dist/directives/KeyboardControls.d.ts.map +1 -1
- package/dist/directives/index.d.ts +9 -1
- package/dist/directives/index.d.ts.map +1 -1
- package/dist/{index-BLbc2zG5.js → index-B9ATEmLe.js} +3926 -3564
- package/dist/index-B9ATEmLe.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.js +6 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +68 -57
- package/package.json +2 -1
- package/src/components/Sprite.ts +87 -3
- package/src/directives/Controls.ts +182 -0
- package/src/directives/ControlsBase.ts +266 -0
- package/src/directives/GamepadControls.ts +515 -0
- package/src/directives/KeyboardControls.ts +66 -426
- package/src/directives/index.ts +9 -6
- package/src/index.ts +1 -1
- package/dist/index-BLbc2zG5.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,64 +1,75 @@
|
|
|
1
|
-
import { h as a } from "./index-
|
|
2
|
-
import { A as r,
|
|
1
|
+
import { h as a } from "./index-B9ATEmLe.js";
|
|
2
|
+
import { A as r, U as o, W as n, o as l, r as c, p, C as S, d as u, L as m, Q as g, ag as d, f as b, D as C, af as T, ad as j, t as w, G as D, q as f, c as v, I as E, K as O, M as h, N as y, O as P, P as V, ae as k, R as x, x as A, S as B, e as G, y as H, w as M, B as N, H as R, T as q, v as I, b as K, z as U, J as z, V as F, ac as J, ab as L, a9 as Q, g as W, a0 as X, _ as Y, a1 as Z, j as _, a5 as $, aa, k as sa, l as ea, X as ta, m as ia, i as ra, Y as oa, n as na, a6 as la, $ as ca, a3 as pa, a2 as Sa, a8 as ua, Z as ma, s as ga, a4 as da, a7 as ba, a as Ca, u as Ta } from "./index-B9ATEmLe.js";
|
|
3
3
|
const e = a.Howler;
|
|
4
4
|
export {
|
|
5
5
|
r as ArraySubject,
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
o as Button,
|
|
7
|
+
n as ButtonState,
|
|
8
|
+
l as Canvas,
|
|
9
|
+
c as Circle,
|
|
10
10
|
p as Container,
|
|
11
|
-
S as
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
g as
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
C as
|
|
18
|
-
|
|
11
|
+
S as ControlsBase,
|
|
12
|
+
u as ControlsDirective,
|
|
13
|
+
m as DOMContainer,
|
|
14
|
+
g as DOMElement,
|
|
15
|
+
d as DisplayObject,
|
|
16
|
+
b as Drag,
|
|
17
|
+
C as Drop,
|
|
18
|
+
T as EVENTS,
|
|
19
|
+
j as Easing,
|
|
20
|
+
w as Ellipse,
|
|
21
|
+
D as GamepadControls,
|
|
22
|
+
f as Graphics,
|
|
23
|
+
v as Howl,
|
|
19
24
|
e as Howler,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
25
|
+
E as Input,
|
|
26
|
+
O as KeyboardControls,
|
|
27
|
+
h as Mesh,
|
|
28
|
+
y as NineSliceSprite,
|
|
29
|
+
P as ObjectSubject,
|
|
30
|
+
V as ParticlesEmitter,
|
|
31
|
+
k as RadialGradient,
|
|
32
|
+
x as Rect,
|
|
33
|
+
A as Scene,
|
|
34
|
+
B as Scheduler,
|
|
35
|
+
G as Sound,
|
|
36
|
+
H as Sprite,
|
|
37
|
+
M as Svg,
|
|
38
|
+
N as Text,
|
|
39
|
+
R as TilingSprite,
|
|
40
|
+
q as Transition,
|
|
41
|
+
I as Triangle,
|
|
42
|
+
K as Utils,
|
|
43
|
+
U as Video,
|
|
44
|
+
z as Viewport,
|
|
45
|
+
F as ViewportFollow,
|
|
46
|
+
J as animatedSequence,
|
|
47
|
+
L as animatedSignal,
|
|
48
|
+
Q as bootstrapCanvas,
|
|
49
|
+
W as computed,
|
|
50
|
+
X as cond,
|
|
51
|
+
Y as createComponent,
|
|
52
|
+
Z as currentSubscriptionsTracker,
|
|
53
|
+
_ as effect,
|
|
54
|
+
$ as h,
|
|
55
|
+
aa as isAnimatedSignal,
|
|
56
|
+
sa as isArraySubject,
|
|
57
|
+
ea as isComputed,
|
|
58
|
+
ta as isElement,
|
|
59
|
+
ia as isObjectSubject,
|
|
60
|
+
ra as isObservable,
|
|
61
|
+
oa as isPrimitive,
|
|
62
|
+
na as isSignal,
|
|
63
|
+
la as isTrigger,
|
|
64
|
+
ca as loop,
|
|
65
|
+
pa as mount,
|
|
66
|
+
Sa as mountTracker,
|
|
67
|
+
ua as on,
|
|
68
|
+
ma as registerComponent,
|
|
69
|
+
ga as signal,
|
|
70
|
+
da as tick,
|
|
71
|
+
ba as trigger,
|
|
72
|
+
Ca as useDefineProps,
|
|
73
|
+
Ta as useProps
|
|
63
74
|
};
|
|
64
75
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "canvasengine",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"@pixi/layout": "^3.0.2",
|
|
13
13
|
"@signe/reactive": "^2.3.3",
|
|
14
14
|
"howler": "^2.2.4",
|
|
15
|
+
"joypad.js": "^2.3.5",
|
|
15
16
|
"pixi-filters": "^6.0.5",
|
|
16
17
|
"pixi-viewport": "^6.0.3",
|
|
17
18
|
"popmotion": "^11.0.5",
|
package/src/components/Sprite.ts
CHANGED
|
@@ -86,10 +86,65 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
86
86
|
|
|
87
87
|
private currentAnimationContainer: Container | null = null;
|
|
88
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Auto-detects image dimensions by loading the image and reading its natural size
|
|
91
|
+
* This is used when width/height are not explicitly provided in the spritesheet definition
|
|
92
|
+
*
|
|
93
|
+
* @param imagePath - Path to the image file
|
|
94
|
+
* @returns Object containing the detected width and height of the image
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const { width, height } = await sprite.detectImageDimensions('path/to/image.png');
|
|
99
|
+
* // width: 256, height: 128
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
private async detectImageDimensions(imagePath: string): Promise<{ width: number; height: number }> {
|
|
103
|
+
if (!imagePath || typeof imagePath !== 'string' || imagePath.trim() === '') {
|
|
104
|
+
throw new Error(`Invalid image path provided to detectImageDimensions: ${imagePath}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const texture = await Assets.load(imagePath);
|
|
108
|
+
return {
|
|
109
|
+
width: texture.width,
|
|
110
|
+
height: texture.height,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Creates textures from a spritesheet image by cutting it into frames
|
|
116
|
+
* Automatically detects image dimensions if width/height are not provided
|
|
117
|
+
*
|
|
118
|
+
* @param options - Texture options containing image path, dimensions, and frame configuration
|
|
119
|
+
* @returns A 2D array of textures organized by rows and columns
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* // With explicit dimensions
|
|
124
|
+
* const textures = await sprite.createTextures({
|
|
125
|
+
* image: 'path/to/image.png',
|
|
126
|
+
* width: 256,
|
|
127
|
+
* height: 128,
|
|
128
|
+
* framesWidth: 4,
|
|
129
|
+
* framesHeight: 2,
|
|
130
|
+
* spriteWidth: 64,
|
|
131
|
+
* spriteHeight: 64
|
|
132
|
+
* });
|
|
133
|
+
*
|
|
134
|
+
* // Without dimensions (automatically detected)
|
|
135
|
+
* const textures = await sprite.createTextures({
|
|
136
|
+
* image: 'path/to/image.png',
|
|
137
|
+
* framesWidth: 4,
|
|
138
|
+
* framesHeight: 2,
|
|
139
|
+
* spriteWidth: 64,
|
|
140
|
+
* spriteHeight: 64
|
|
141
|
+
* });
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
89
144
|
private async createTextures(
|
|
90
145
|
options: Required<TextureOptionsMerging>
|
|
91
146
|
): Promise<Texture[][]> {
|
|
92
|
-
|
|
147
|
+
let { width, height, framesHeight, framesWidth, image, offset } = options;
|
|
93
148
|
|
|
94
149
|
if (!image || typeof image !== 'string' || image.trim() === '') {
|
|
95
150
|
console.warn('Invalid image path provided to createTextures:', image);
|
|
@@ -97,6 +152,17 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
97
152
|
}
|
|
98
153
|
|
|
99
154
|
const texture = await Assets.load(image);
|
|
155
|
+
|
|
156
|
+
// Auto-detect width and height from the image if not provided
|
|
157
|
+
if (!width || width <= 0) {
|
|
158
|
+
width = texture.width;
|
|
159
|
+
options.width = width;
|
|
160
|
+
}
|
|
161
|
+
if (!height || height <= 0) {
|
|
162
|
+
height = texture.height;
|
|
163
|
+
options.height = height;
|
|
164
|
+
}
|
|
165
|
+
|
|
100
166
|
const spriteWidth = options.spriteWidth;
|
|
101
167
|
const spriteHeight = options.spriteHeight;
|
|
102
168
|
const frames: Texture[][] = [];
|
|
@@ -155,12 +221,30 @@ export class CanvasSprite extends DisplayObject(PixiSprite) {
|
|
|
155
221
|
} as any;
|
|
156
222
|
const {
|
|
157
223
|
rectWidth,
|
|
158
|
-
width = 0,
|
|
224
|
+
width: widthOption = 0,
|
|
159
225
|
framesWidth = 1,
|
|
160
226
|
rectHeight,
|
|
161
|
-
height = 0,
|
|
227
|
+
height: heightOption = 0,
|
|
162
228
|
framesHeight = 1,
|
|
229
|
+
image,
|
|
163
230
|
} = optionsTextures;
|
|
231
|
+
|
|
232
|
+
// Auto-detect width and height from the image if not provided
|
|
233
|
+
let width = widthOption;
|
|
234
|
+
let height = heightOption;
|
|
235
|
+
|
|
236
|
+
if (image && ((!width || width <= 0) || (!height || height <= 0))) {
|
|
237
|
+
const dimensions = await this.detectImageDimensions(image);
|
|
238
|
+
if (!width || width <= 0) {
|
|
239
|
+
width = dimensions.width;
|
|
240
|
+
optionsTextures.width = width;
|
|
241
|
+
}
|
|
242
|
+
if (!height || height <= 0) {
|
|
243
|
+
height = dimensions.height;
|
|
244
|
+
optionsTextures.height = height;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
164
248
|
optionsTextures.spriteWidth = rectWidth ? rectWidth : width / framesWidth;
|
|
165
249
|
optionsTextures.spriteHeight = rectHeight
|
|
166
250
|
? rectHeight
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { Directive, registerDirective } from "../engine/directive";
|
|
2
|
+
import { Element } from "../engine/reactive";
|
|
3
|
+
import { ControlsBase, Controls } from "./ControlsBase";
|
|
4
|
+
import { KeyboardControls } from "./KeyboardControls";
|
|
5
|
+
import { GamepadControls, GamepadConfig } from "./GamepadControls";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Controls directive that coordinates keyboard and gamepad input systems
|
|
9
|
+
*
|
|
10
|
+
* This directive automatically activates both keyboard and gamepad controls when available.
|
|
11
|
+
* The gamepad is automatically enabled if joypad.js is detected in the environment.
|
|
12
|
+
*
|
|
13
|
+
* Both systems share the same control configuration and can work simultaneously.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```html
|
|
17
|
+
* <Sprite
|
|
18
|
+
* image="path/to/image.png"
|
|
19
|
+
* controls={controlsConfig}
|
|
20
|
+
* x={x}
|
|
21
|
+
* y={y}
|
|
22
|
+
* />
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export class ControlsDirective extends Directive {
|
|
26
|
+
private keyboardControls: KeyboardControls | null = null;
|
|
27
|
+
private gamepadControls: GamepadControls | null = null;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Initialize the controls directive
|
|
31
|
+
* Sets up keyboard and gamepad controls if available
|
|
32
|
+
*/
|
|
33
|
+
onInit(element: Element) {
|
|
34
|
+
const value = element.props.controls?.value ?? element.props.controls;
|
|
35
|
+
if (!value) return;
|
|
36
|
+
|
|
37
|
+
// Initialize keyboard controls (always available)
|
|
38
|
+
this.keyboardControls = new KeyboardControls();
|
|
39
|
+
this.keyboardControls.setInputs(value as Controls);
|
|
40
|
+
this.keyboardControls.start();
|
|
41
|
+
|
|
42
|
+
// Initialize gamepad controls if gamepad config is present
|
|
43
|
+
// GamepadControls will handle joypad.js availability internally
|
|
44
|
+
const gamepadConfig = (value as Controls & { gamepad?: GamepadConfig }).gamepad;
|
|
45
|
+
if (gamepadConfig !== undefined && gamepadConfig.enabled !== false) {
|
|
46
|
+
this.gamepadControls = new GamepadControls();
|
|
47
|
+
this.gamepadControls.setInputs(value as Controls & { gamepad?: GamepadConfig });
|
|
48
|
+
this.gamepadControls.start();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Mount hook (no specific action needed)
|
|
54
|
+
*/
|
|
55
|
+
onMount(element: Element) {}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Update controls configuration
|
|
59
|
+
* Updates both keyboard and gamepad controls
|
|
60
|
+
*/
|
|
61
|
+
onUpdate(props: any) {
|
|
62
|
+
const value = props.controls?.value ?? props.controls;
|
|
63
|
+
if (!value) return;
|
|
64
|
+
|
|
65
|
+
if (this.keyboardControls) {
|
|
66
|
+
this.keyboardControls.setInputs(value as Controls);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (this.gamepadControls) {
|
|
70
|
+
this.gamepadControls.setInputs(value as Controls & { gamepad?: GamepadConfig });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Cleanup and destroy all control systems
|
|
76
|
+
*/
|
|
77
|
+
onDestroy(element: Element) {
|
|
78
|
+
if (this.keyboardControls) {
|
|
79
|
+
this.keyboardControls.destroy();
|
|
80
|
+
this.keyboardControls = null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (this.gamepadControls) {
|
|
84
|
+
this.gamepadControls.destroy();
|
|
85
|
+
this.gamepadControls = null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get a control by input name
|
|
91
|
+
* Delegates to keyboard controls (primary system)
|
|
92
|
+
*
|
|
93
|
+
* @param inputName - Name of the input/key
|
|
94
|
+
* @returns BoundKey if found, undefined otherwise
|
|
95
|
+
*/
|
|
96
|
+
getControl(inputName: string) {
|
|
97
|
+
return this.keyboardControls?.getControl(inputName);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get all bound controls
|
|
102
|
+
* Delegates to keyboard controls (primary system)
|
|
103
|
+
*
|
|
104
|
+
* @returns Object mapping input names to BoundKey objects
|
|
105
|
+
*/
|
|
106
|
+
getControls() {
|
|
107
|
+
return this.keyboardControls?.getControls() || {};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Apply a control action programmatically
|
|
112
|
+
* Applies to both keyboard and gamepad if available
|
|
113
|
+
*
|
|
114
|
+
* @param controlName - Name of the control
|
|
115
|
+
* @param isDown - Whether the control is pressed (true) or released (false)
|
|
116
|
+
* @returns Promise that resolves when the action is complete
|
|
117
|
+
*/
|
|
118
|
+
async applyControl(controlName: string | number, isDown?: boolean): Promise<void> {
|
|
119
|
+
if (this.keyboardControls) {
|
|
120
|
+
await this.keyboardControls.applyControl(controlName, isDown);
|
|
121
|
+
}
|
|
122
|
+
if (this.gamepadControls) {
|
|
123
|
+
await this.gamepadControls.applyControl(controlName, isDown);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Stop listening to inputs
|
|
129
|
+
* Stops both keyboard and gamepad input processing
|
|
130
|
+
*/
|
|
131
|
+
stopInputs() {
|
|
132
|
+
if (this.keyboardControls) {
|
|
133
|
+
this.keyboardControls.stopInputs();
|
|
134
|
+
}
|
|
135
|
+
if (this.gamepadControls) {
|
|
136
|
+
this.gamepadControls.stopInputs();
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Resume listening to inputs
|
|
142
|
+
* Resumes both keyboard and gamepad input processing
|
|
143
|
+
*/
|
|
144
|
+
listenInputs() {
|
|
145
|
+
if (this.keyboardControls) {
|
|
146
|
+
this.keyboardControls.listenInputs();
|
|
147
|
+
}
|
|
148
|
+
if (this.gamepadControls) {
|
|
149
|
+
this.gamepadControls.listenInputs();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Get the current controls configuration
|
|
155
|
+
* Returns keyboard controls options (both systems share the same config)
|
|
156
|
+
*
|
|
157
|
+
* @returns The controls options object
|
|
158
|
+
*/
|
|
159
|
+
get options(): Controls {
|
|
160
|
+
return this.keyboardControls?.options || {};
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Get the keyboard controls instance
|
|
165
|
+
*
|
|
166
|
+
* @returns KeyboardControls instance or null
|
|
167
|
+
*/
|
|
168
|
+
get keyboard(): KeyboardControls | null {
|
|
169
|
+
return this.keyboardControls;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Get the gamepad controls instance
|
|
174
|
+
*
|
|
175
|
+
* @returns GamepadControls instance or null
|
|
176
|
+
*/
|
|
177
|
+
get gamepad(): GamepadControls | null {
|
|
178
|
+
return this.gamepadControls;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
registerDirective('controls', ControlsDirective);
|