@kayelaa/canvas 0.1.14 → 0.2.0
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/README.md +264 -73
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/jsx-dev-runtime.cjs +2 -2
- package/dist/jsx-dev-runtime.d.cts +2 -2
- package/dist/jsx-dev-runtime.d.ts +2 -2
- package/dist/jsx-dev-runtime.js +2 -2
- package/dist/jsx-runtime.cjs +2 -2
- package/dist/jsx-runtime.d.cts +2 -2
- package/dist/jsx-runtime.d.ts +2 -2
- package/dist/jsx-runtime.js +2 -2
- package/dist/{kayla-internals-BsxRqVsK.d.ts → kayla-internals-8Xl7b2Jc.d.ts} +698 -225
- package/dist/{kayla-internals-DVENIMGb.d.cts → kayla-internals-CudoMM3W.d.cts} +698 -225
- package/dist/kayla.cjs +2 -2
- package/dist/kayla.d.cts +30 -11
- package/dist/kayla.d.ts +30 -11
- package/dist/kayla.js +2 -2
- package/dist/{lea-DvxsutSf.d.cts → lea-k7IGP_-W.d.cts} +9 -1
- package/dist/{lea-DvxsutSf.d.ts → lea-k7IGP_-W.d.ts} +9 -1
- package/dist/lea.cjs +1 -1
- package/dist/lea.d.cts +1 -1
- package/dist/lea.d.ts +1 -1
- package/dist/lea.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,15 +15,15 @@ It's a **very thin declarative layer** on top of LEA — all performance-critica
|
|
|
15
15
|
|
|
16
16
|
Made by **Kayelaa Cagara** (@LianeKayee39 on X / GitHub) in Calamba, Philippines.
|
|
17
17
|
|
|
18
|
-
## API Reference (worth checking if you want a true API reference for every variables, properties, etc)
|
|
18
|
+
## API Reference for missing things in this docs (worth checking if you want a true API reference for every variables, properties, etc)
|
|
19
19
|
[API Reference](https://lianecagara.github.io/kayelaa-canvas-docs/)
|
|
20
20
|
|
|
21
|
-
**
|
|
21
|
+
**The Documentation below would get INACCURATE in the future. Always visit the .d.ts files or the API Reference for reliable documentation.**
|
|
22
22
|
|
|
23
23
|
## Quick Start — Fully Typed Version (copy-paste this)
|
|
24
24
|
|
|
25
|
-
```
|
|
26
|
-
//
|
|
25
|
+
```tsx
|
|
26
|
+
// demo.ts v1.3
|
|
27
27
|
/** @jsxImportSource @kayelaa/canvas */
|
|
28
28
|
import {
|
|
29
29
|
createGame,
|
|
@@ -32,72 +32,160 @@ import {
|
|
|
32
32
|
useSelf,
|
|
33
33
|
useTick,
|
|
34
34
|
usePaint,
|
|
35
|
-
useEntity,
|
|
36
|
-
FC,
|
|
37
35
|
FCProps,
|
|
38
|
-
useEffect,
|
|
39
36
|
useRef,
|
|
40
37
|
Kayla,
|
|
41
38
|
FCExports,
|
|
42
39
|
useExports,
|
|
40
|
+
useRect,
|
|
41
|
+
useFiberControl,
|
|
42
|
+
useInitialization,
|
|
43
|
+
LEA,
|
|
44
|
+
useGlobalClick,
|
|
45
|
+
useClick,
|
|
46
|
+
useCurrentTicker,
|
|
47
|
+
createContext,
|
|
48
|
+
KaylaRect,
|
|
49
|
+
useContext,
|
|
43
50
|
} from "@kayelaa/canvas/kayla";
|
|
44
|
-
import { Vector2 } from "@kayelaa/canvas/lea";
|
|
45
51
|
|
|
46
52
|
interface MouseFollowerProps extends FCProps {
|
|
47
53
|
initialX?: number;
|
|
48
54
|
initialY?: number;
|
|
55
|
+
color: string;
|
|
56
|
+
initialSpeed?: number;
|
|
57
|
+
freeXY?: boolean;
|
|
49
58
|
}
|
|
50
59
|
|
|
51
60
|
interface MouseFollowerExports extends FCExports {
|
|
52
61
|
jump(): void;
|
|
53
62
|
getHealth(): number;
|
|
63
|
+
rect: KaylaRect;
|
|
64
|
+
health: number;
|
|
54
65
|
}
|
|
55
66
|
|
|
56
|
-
const
|
|
67
|
+
const MainContext = createContext<{
|
|
68
|
+
members: KaylaRect[];
|
|
69
|
+
player: MouseFollowerExports | null;
|
|
70
|
+
}>(null);
|
|
71
|
+
|
|
72
|
+
const MouseFollower: Kayla.FC<MouseFollowerProps, MouseFollowerExports> = ({
|
|
57
73
|
initialX = 0,
|
|
58
74
|
initialY = 0,
|
|
75
|
+
color,
|
|
76
|
+
initialSpeed,
|
|
77
|
+
freeXY = true,
|
|
59
78
|
}) => {
|
|
60
79
|
const rect = useRect();
|
|
80
|
+
interface CableVecInfo {
|
|
81
|
+
remainingMS: number;
|
|
82
|
+
vec: LEA.Vector2;
|
|
83
|
+
totalDist: number;
|
|
84
|
+
}
|
|
85
|
+
const cableVecs = useRef<CableVecInfo[]>([]);
|
|
86
|
+
const cableConfig = useSelf(() => ({
|
|
87
|
+
durationMS: 1000,
|
|
88
|
+
}));
|
|
89
|
+
|
|
90
|
+
useGlobalClick((pos, type) => {
|
|
91
|
+
if (rect.isHovered()) return;
|
|
92
|
+
if (type === "left") {
|
|
93
|
+
const start = rect.pos.clone();
|
|
94
|
+
cableVecs.current.push({
|
|
95
|
+
remainingMS: cableConfig.durationMS,
|
|
96
|
+
vec: pos.clone(),
|
|
97
|
+
totalDist: pos.subtract(start).length,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
useTick((delta) => {
|
|
103
|
+
const remaining: typeof cableVecs.current = [];
|
|
104
|
+
let newestTotalDist = cableVecs.current.at(-1)?.totalDist ?? 0;
|
|
105
|
+
for (const ref of cableVecs.current) {
|
|
106
|
+
if (ref.remainingMS <= 0.01) continue;
|
|
107
|
+
const { vec: target } = ref;
|
|
108
|
+
const dir = target.subtract(rect.pos);
|
|
109
|
+
const moveLen = (newestTotalDist / cableConfig.durationMS) * delta * 1000;
|
|
110
|
+
const added = dir.normalized().scale(moveLen);
|
|
111
|
+
rect.x += added.x;
|
|
112
|
+
rect.y += added.y;
|
|
113
|
+
ref.remainingMS -= delta * 1000;
|
|
114
|
+
if (ref.remainingMS > 0.01) {
|
|
115
|
+
remaining.push(ref);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
cableVecs.current = remaining;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const fiber = useFiberControl();
|
|
122
|
+
const ticker = useCurrentTicker();
|
|
123
|
+
const mainContext = useContext(MainContext);
|
|
61
124
|
|
|
62
125
|
useInitialization(() => {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
126
|
+
if (freeXY) {
|
|
127
|
+
rect.x = initialX;
|
|
128
|
+
rect.y = initialY;
|
|
129
|
+
rect.width = 40;
|
|
130
|
+
rect.height = 40;
|
|
131
|
+
rect.z = 100;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
console.log(`New Follower: ${fiber.key}`);
|
|
135
|
+
console.log({ mems: mainContext.members });
|
|
136
|
+
mainContext.player = me;
|
|
137
|
+
return () => {
|
|
138
|
+
console.log(`Removed Follower: ${fiber.key}`);
|
|
139
|
+
mainContext.player = null;
|
|
140
|
+
};
|
|
66
141
|
});
|
|
67
142
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
143
|
+
useClick(() => {
|
|
144
|
+
const a = 40;
|
|
145
|
+
rect.width += a;
|
|
146
|
+
rect.height += a;
|
|
147
|
+
ticker.createTween(
|
|
148
|
+
{
|
|
149
|
+
ms: 3000,
|
|
150
|
+
easing: LEA.LeaUtilsII.easeOutExpo,
|
|
151
|
+
delta: -a,
|
|
152
|
+
},
|
|
153
|
+
(da) => {
|
|
154
|
+
rect.width += da;
|
|
155
|
+
rect.height += da;
|
|
156
|
+
},
|
|
157
|
+
);
|
|
158
|
+
});
|
|
71
159
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
160
|
+
const me: MouseFollowerExports = useSelf(() => ({
|
|
161
|
+
speed: initialSpeed ?? LEA.LeaUtilsII.randomLerp(150, 300),
|
|
162
|
+
health: 100,
|
|
163
|
+
getHealth() {
|
|
164
|
+
return this.health;
|
|
165
|
+
},
|
|
166
|
+
get rect() {
|
|
167
|
+
return rect;
|
|
81
168
|
},
|
|
82
|
-
|
|
83
169
|
jump() {
|
|
84
170
|
rect.y -= 100;
|
|
85
171
|
},
|
|
86
172
|
}));
|
|
87
173
|
|
|
88
|
-
useTick((delta) => self.tick(delta));
|
|
89
|
-
|
|
90
174
|
usePaint((ctx) => {
|
|
91
|
-
ctx.
|
|
92
|
-
ctx.
|
|
175
|
+
ctx.globalAlpha = 1;
|
|
176
|
+
ctx.strokeStyle = "white";
|
|
177
|
+
ctx.lineWidth = 10;
|
|
178
|
+
for (const { vec: cable } of cableVecs.current) {
|
|
179
|
+
ctx.beginPath();
|
|
180
|
+
ctx.moveTo(rect.x, rect.y);
|
|
181
|
+
ctx.lineTo(cable.x, cable.y);
|
|
182
|
+
ctx.stroke();
|
|
183
|
+
}
|
|
184
|
+
ctx.fillStyle = color ?? (me.health > 50 ? "#00aaff" : "#ff4444");
|
|
185
|
+
ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
|
|
93
186
|
});
|
|
94
187
|
|
|
95
|
-
useExports(MouseFollower, () =>
|
|
96
|
-
jump: self.jump,
|
|
97
|
-
getHealth: () => self.health,
|
|
98
|
-
}));
|
|
99
|
-
|
|
100
|
-
return [];
|
|
188
|
+
useExports(MouseFollower, () => me);
|
|
101
189
|
};
|
|
102
190
|
|
|
103
191
|
// Setup (run once)
|
|
@@ -108,11 +196,15 @@ renderer.listenPointerUpdates();
|
|
|
108
196
|
const game = createGame({ width: 800, height: 600, updateHz: 1000 / 60 });
|
|
109
197
|
const scene = createScene("main");
|
|
110
198
|
|
|
111
|
-
scene.spawn(<MouseFollower initialX={400} initialY={300} />);
|
|
112
|
-
|
|
113
199
|
renderer.attachTo(game);
|
|
114
200
|
scene.attachTo(game);
|
|
115
201
|
|
|
202
|
+
scene.spawn(
|
|
203
|
+
<MainContext.Provider value={{ members: [], player: null }}>
|
|
204
|
+
<MouseFollower initialX={400} initialY={300} color="red" />
|
|
205
|
+
</MainContext.Provider>,
|
|
206
|
+
);
|
|
207
|
+
|
|
116
208
|
game.start();
|
|
117
209
|
```
|
|
118
210
|
|
|
@@ -144,11 +236,12 @@ npm install @kayelaa/canvas
|
|
|
144
236
|
npm run dev
|
|
145
237
|
```
|
|
146
238
|
|
|
147
|
-
## No Vite? Try our ESM Build! Pure HTML + JS + Import maps
|
|
239
|
+
## No Vite/Bundler? Try our ESM Build! Pure HTML + JS + Import maps
|
|
148
240
|
|
|
149
241
|
```html
|
|
150
242
|
<!DOCTYPE html>
|
|
151
243
|
<html lang="en">
|
|
244
|
+
|
|
152
245
|
<head>
|
|
153
246
|
<meta charset="UTF-8">
|
|
154
247
|
<title>Kayla Canvas Test - No JSX</title>
|
|
@@ -157,6 +250,7 @@ npm run dev
|
|
|
157
250
|
margin: 0;
|
|
158
251
|
overflow: hidden;
|
|
159
252
|
}
|
|
253
|
+
|
|
160
254
|
canvas {
|
|
161
255
|
display: block;
|
|
162
256
|
background: #111;
|
|
@@ -171,10 +265,14 @@ npm run dev
|
|
|
171
265
|
}
|
|
172
266
|
</script>
|
|
173
267
|
</head>
|
|
268
|
+
|
|
174
269
|
<body>
|
|
175
270
|
<canvas id="game" width="800" height="600"></canvas>
|
|
176
271
|
|
|
177
272
|
<script type="module">
|
|
273
|
+
// demo.ts v1.3
|
|
274
|
+
// @ts-nocheck
|
|
275
|
+
/** @jsxImportSource @kayelaa/canvas */
|
|
178
276
|
import {
|
|
179
277
|
createGame,
|
|
180
278
|
createScene,
|
|
@@ -182,77 +280,170 @@ npm run dev
|
|
|
182
280
|
useSelf,
|
|
183
281
|
useTick,
|
|
184
282
|
usePaint,
|
|
185
|
-
useEntity,
|
|
186
|
-
createElement,
|
|
187
|
-
useEffect,
|
|
188
283
|
useRef,
|
|
189
|
-
|
|
284
|
+
Kayla,
|
|
285
|
+
useExports,
|
|
286
|
+
useRect,
|
|
287
|
+
useFiberControl,
|
|
288
|
+
useInitialization,
|
|
289
|
+
LEA,
|
|
290
|
+
useGlobalClick,
|
|
291
|
+
useClick,
|
|
292
|
+
useCurrentTicker,
|
|
293
|
+
createContext,
|
|
294
|
+
KaylaRect,
|
|
295
|
+
useContext,
|
|
296
|
+
createElement,
|
|
190
297
|
} from "@kayelaa/canvas/kayla";
|
|
191
298
|
|
|
299
|
+
const MainContext = createContext(null);
|
|
300
|
+
|
|
192
301
|
const MouseFollower = ({
|
|
193
302
|
initialX = 0,
|
|
194
303
|
initialY = 0,
|
|
304
|
+
color,
|
|
305
|
+
initialSpeed,
|
|
306
|
+
freeXY = true,
|
|
195
307
|
}) => {
|
|
196
308
|
const rect = useRect();
|
|
197
309
|
|
|
310
|
+
const cableVecs = useRef([]);
|
|
311
|
+
const cableConfig = useSelf(() => ({
|
|
312
|
+
durationMS: 1000,
|
|
313
|
+
}));
|
|
314
|
+
|
|
315
|
+
useGlobalClick((pos, type) => {
|
|
316
|
+
if (rect.isHovered()) return;
|
|
317
|
+
if (type === "left") {
|
|
318
|
+
const start = rect.pos.clone();
|
|
319
|
+
cableVecs.current.push({
|
|
320
|
+
remainingMS: cableConfig.durationMS,
|
|
321
|
+
vec: pos.clone(),
|
|
322
|
+
totalDist: pos.subtract(start).length,
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
useTick((delta) => {
|
|
328
|
+
const remaining = [];
|
|
329
|
+
let newestTotalDist = cableVecs.current.at(-1)?.totalDist ?? 0;
|
|
330
|
+
for (const ref of cableVecs.current) {
|
|
331
|
+
if (ref.remainingMS <= 0.01) continue;
|
|
332
|
+
const { vec: target } = ref;
|
|
333
|
+
const dir = target.subtract(rect.pos);
|
|
334
|
+
const moveLen = (newestTotalDist / cableConfig.durationMS) * delta * 1000;
|
|
335
|
+
const added = dir.normalized().scale(moveLen);
|
|
336
|
+
rect.x += added.x;
|
|
337
|
+
rect.y += added.y;
|
|
338
|
+
ref.remainingMS -= delta * 1000;
|
|
339
|
+
if (ref.remainingMS > 0.01) {
|
|
340
|
+
remaining.push(ref);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
cableVecs.current = remaining;
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
const fiber = useFiberControl();
|
|
347
|
+
const ticker = useCurrentTicker();
|
|
348
|
+
const mainContext = useContext(MainContext);
|
|
349
|
+
|
|
198
350
|
useInitialization(() => {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
351
|
+
if (freeXY) {
|
|
352
|
+
rect.x = initialX;
|
|
353
|
+
rect.y = initialY;
|
|
354
|
+
rect.width = 40;
|
|
355
|
+
rect.height = 40;
|
|
356
|
+
rect.z = 100;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
console.log(`New Follower: ${fiber.key}`);
|
|
360
|
+
console.log({ mems: mainContext.members });
|
|
361
|
+
mainContext.player = me;
|
|
362
|
+
return () => {
|
|
363
|
+
console.log(`Removed Follower: ${fiber.key}`);
|
|
364
|
+
mainContext.player = null;
|
|
365
|
+
};
|
|
202
366
|
});
|
|
203
367
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
368
|
+
useClick(() => {
|
|
369
|
+
const a = 40;
|
|
370
|
+
rect.width += a;
|
|
371
|
+
rect.height += a;
|
|
372
|
+
ticker.createTween(
|
|
373
|
+
{
|
|
374
|
+
ms: 3000,
|
|
375
|
+
easing: LEA.LeaUtilsII.easeOutExpo,
|
|
376
|
+
delta: -a,
|
|
377
|
+
},
|
|
378
|
+
(da) => {
|
|
379
|
+
rect.width += da;
|
|
380
|
+
rect.height += da;
|
|
381
|
+
},
|
|
382
|
+
);
|
|
383
|
+
});
|
|
207
384
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
385
|
+
const me = useSelf(() => ({
|
|
386
|
+
speed: initialSpeed ?? LEA.LeaUtilsII.randomLerp(150, 300),
|
|
387
|
+
health: 100,
|
|
388
|
+
getHealth() {
|
|
389
|
+
return this.health;
|
|
390
|
+
},
|
|
391
|
+
get rect() {
|
|
392
|
+
return rect;
|
|
217
393
|
},
|
|
218
|
-
|
|
219
394
|
jump() {
|
|
220
395
|
rect.y -= 100;
|
|
221
396
|
},
|
|
222
397
|
}));
|
|
223
398
|
|
|
224
|
-
useTick((delta) => self.tick(delta));
|
|
225
|
-
|
|
226
399
|
usePaint((ctx) => {
|
|
227
|
-
ctx.
|
|
228
|
-
ctx.
|
|
400
|
+
ctx.globalAlpha = 1;
|
|
401
|
+
ctx.strokeStyle = "white";
|
|
402
|
+
ctx.lineWidth = 10;
|
|
403
|
+
for (const { vec: cable } of cableVecs.current) {
|
|
404
|
+
ctx.beginPath();
|
|
405
|
+
ctx.moveTo(rect.x, rect.y);
|
|
406
|
+
ctx.lineTo(cable.x, cable.y);
|
|
407
|
+
ctx.stroke();
|
|
408
|
+
}
|
|
409
|
+
ctx.fillStyle = color ?? (me.health > 50 ? "#00aaff" : "#ff4444");
|
|
410
|
+
ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
|
|
229
411
|
});
|
|
230
412
|
|
|
231
|
-
useExports(MouseFollower, () =>
|
|
232
|
-
jump: self.jump,
|
|
233
|
-
getHealth: () => self.health,
|
|
234
|
-
}));
|
|
235
|
-
|
|
236
|
-
return [];
|
|
413
|
+
useExports(MouseFollower, () => me);
|
|
237
414
|
};
|
|
238
415
|
|
|
239
|
-
// Setup
|
|
416
|
+
// Setup (run once)
|
|
240
417
|
const canvas = document.getElementById("game");
|
|
241
418
|
const renderer = createRenderer(canvas);
|
|
242
419
|
renderer.listenPointerUpdates();
|
|
243
420
|
|
|
244
|
-
const game = createGame({ width: 800, height: 600, updateHz: 1000/60 });
|
|
421
|
+
const game = createGame({ width: 800, height: 600, updateHz: 1000 / 60 });
|
|
245
422
|
const scene = createScene("main");
|
|
246
423
|
|
|
247
|
-
// Spawn player using createElement
|
|
248
|
-
scene.spawn(createElement(MouseFollower, { initialX: 400, initialY: 300 }));
|
|
249
|
-
|
|
250
424
|
renderer.attachTo(game);
|
|
251
425
|
scene.attachTo(game);
|
|
252
426
|
|
|
427
|
+
scene.spawn(
|
|
428
|
+
createElement(MainContext.Provider, {
|
|
429
|
+
value: {
|
|
430
|
+
members: [],
|
|
431
|
+
player: null,
|
|
432
|
+
},
|
|
433
|
+
children: [
|
|
434
|
+
createElement(MouseFollower, {
|
|
435
|
+
initialX: 400,
|
|
436
|
+
initialY: 300,
|
|
437
|
+
color: "red",
|
|
438
|
+
}),
|
|
439
|
+
],
|
|
440
|
+
}),
|
|
441
|
+
);
|
|
442
|
+
|
|
253
443
|
game.start();
|
|
254
444
|
</script>
|
|
255
445
|
</body>
|
|
446
|
+
|
|
256
447
|
</html>
|
|
257
448
|
```
|
|
258
449
|
|