@jiant/canvable 0.0.1 → 0.0.3
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 +5 -5
- package/dist/main.d.mts +35 -11
- package/dist/main.d.ts +35 -11
- package/dist/main.js +108 -30
- package/dist/main.mjs +106 -30
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Canvable
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Canvable é uma biblioteca para criação de cenas em canvas com um sistema de nós, permitindo a construção de elementos e interações de forma intuitiva, similar a uma engine de jogos 2D. A biblioteca oferece suporte para objetos gráficos, entrada de usuário, câmera, e muito mais, permitindo criar experiências interativas de maneira modular e flexível.
|
|
4
4
|
|
|
5
5
|
## Instalação
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@ CanvasBuilder é uma biblioteca para criação de cenas em canvas com um sistema
|
|
|
9
9
|
Se você está utilizando o NPM, pode instalar a biblioteca com:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install @jiant/
|
|
12
|
+
npm install @jiant/canvable
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### Usando Yarn
|
|
@@ -17,7 +17,7 @@ npm install @jiant/canvasbuilder
|
|
|
17
17
|
Se você está utilizando o Yarn, pode instalar com:
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
yarn add @jiant/
|
|
20
|
+
yarn add @jiant/canvable
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
## Exemplos de Uso
|
|
@@ -27,7 +27,7 @@ yarn add @jiant/canvasbuilder
|
|
|
27
27
|
A seguir está um exemplo básico de como criar uma cena e adicionar um objeto nela:
|
|
28
28
|
|
|
29
29
|
```typescript
|
|
30
|
-
import { Circle, getCanvas, Scene } from "@jiant/
|
|
30
|
+
import { Circle, getCanvas, Scene } from "@jiant/canvable";
|
|
31
31
|
import "./style.css";
|
|
32
32
|
|
|
33
33
|
// Obtendo o canvas
|
package/dist/main.d.mts
CHANGED
|
@@ -2,14 +2,22 @@
|
|
|
2
2
|
* A 2D vector class for mathematical operations and physics calculations
|
|
3
3
|
*/
|
|
4
4
|
declare class Vector2D {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
private _x;
|
|
6
|
+
private _y;
|
|
7
|
+
constructor(x?: number, y?: number);
|
|
8
|
+
onChange: ((delta: Vector2D) => void)[];
|
|
7
9
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @param x - The x
|
|
10
|
-
* @param y - The y component of the vector
|
|
10
|
+
* Sets the x component of the vector and notifies any registered callbacks.
|
|
11
|
+
* @param x - The new x value for the vector.
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
|
+
set x(x: number);
|
|
14
|
+
/**
|
|
15
|
+
* Sets the y component of the vector and notifies any registered callbacks.
|
|
16
|
+
* @param y - The new y value for the vector.
|
|
17
|
+
*/
|
|
18
|
+
set y(y: number);
|
|
19
|
+
get x(): number;
|
|
20
|
+
get y(): number;
|
|
13
21
|
/**
|
|
14
22
|
* Adds another vector to this vector
|
|
15
23
|
* @param vector - The vector to add
|
|
@@ -159,7 +167,7 @@ declare const TWO_PI: number;
|
|
|
159
167
|
|
|
160
168
|
declare class Camera extends Node {
|
|
161
169
|
zoom: number;
|
|
162
|
-
constructor(
|
|
170
|
+
constructor(zoom?: number);
|
|
163
171
|
update(deltaTime: number): void;
|
|
164
172
|
transformCoordinates(position: Vector2D): Vector2D;
|
|
165
173
|
}
|
|
@@ -169,8 +177,10 @@ declare class InputManager extends Node {
|
|
|
169
177
|
private keyJustPressed;
|
|
170
178
|
private mouseState;
|
|
171
179
|
private mouseJustPressed;
|
|
180
|
+
mousePos: Vector2D;
|
|
172
181
|
constructor();
|
|
173
182
|
private setupListeners;
|
|
183
|
+
private handleMouseMove;
|
|
174
184
|
private handleKeyDown;
|
|
175
185
|
private handleKeyUp;
|
|
176
186
|
private handleMouseDown;
|
|
@@ -208,18 +218,24 @@ declare class Scene extends Node {
|
|
|
208
218
|
interface NodeConfig {
|
|
209
219
|
id?: string;
|
|
210
220
|
pos?: Vector2D;
|
|
221
|
+
scene?: Scene;
|
|
211
222
|
}
|
|
212
223
|
declare class Node {
|
|
213
|
-
id: string;
|
|
214
224
|
pos: Vector2D;
|
|
225
|
+
id: string;
|
|
215
226
|
children: Node[];
|
|
216
227
|
scene?: Scene;
|
|
217
|
-
constructor(config?: NodeConfig);
|
|
228
|
+
constructor(scene?: Scene, config?: NodeConfig);
|
|
218
229
|
addObject(object: Node): void;
|
|
219
230
|
removeObject(object: Node): void;
|
|
220
231
|
private generateID;
|
|
221
232
|
}
|
|
222
233
|
|
|
234
|
+
declare abstract class BoundingBox extends Node {
|
|
235
|
+
abstract checkCollision(other: BoundingBox): boolean;
|
|
236
|
+
abstract isPointInside(_point: Vector2D): boolean;
|
|
237
|
+
}
|
|
238
|
+
|
|
223
239
|
interface CircleConfig {
|
|
224
240
|
vel?: Vector2D;
|
|
225
241
|
size?: number;
|
|
@@ -230,10 +246,18 @@ declare class Circle extends Node {
|
|
|
230
246
|
vel: Vector2D;
|
|
231
247
|
size: number;
|
|
232
248
|
friction: number;
|
|
233
|
-
|
|
249
|
+
boundingBox: BoundingBox;
|
|
250
|
+
constructor(scene?: Scene, config?: CircleConfig);
|
|
234
251
|
draw(ctx: CanvasRenderingContext2D, selected?: boolean): void;
|
|
235
252
|
}
|
|
236
253
|
|
|
254
|
+
declare class CircleBoundingBox extends BoundingBox {
|
|
255
|
+
radius: number;
|
|
256
|
+
constructor(scene?: Scene, radius?: number);
|
|
257
|
+
checkCollision(other: BoundingBox): boolean;
|
|
258
|
+
isPointInside(_point: Vector2D): boolean;
|
|
259
|
+
}
|
|
260
|
+
|
|
237
261
|
declare function getCanvas(id: string): HTMLCanvasElement;
|
|
238
262
|
|
|
239
|
-
export { Camera, Circle, type CircleConfig, type Drawable, Node, type NodeConfig, Scene, type SceneOptions, TWO_PI, type Updatable, Vector2D, getCanvas };
|
|
263
|
+
export { BoundingBox, Camera, Circle, CircleBoundingBox, type CircleConfig, type Drawable, Node, type NodeConfig, Scene, type SceneOptions, TWO_PI, type Updatable, Vector2D, getCanvas };
|
package/dist/main.d.ts
CHANGED
|
@@ -2,14 +2,22 @@
|
|
|
2
2
|
* A 2D vector class for mathematical operations and physics calculations
|
|
3
3
|
*/
|
|
4
4
|
declare class Vector2D {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
private _x;
|
|
6
|
+
private _y;
|
|
7
|
+
constructor(x?: number, y?: number);
|
|
8
|
+
onChange: ((delta: Vector2D) => void)[];
|
|
7
9
|
/**
|
|
8
|
-
*
|
|
9
|
-
* @param x - The x
|
|
10
|
-
* @param y - The y component of the vector
|
|
10
|
+
* Sets the x component of the vector and notifies any registered callbacks.
|
|
11
|
+
* @param x - The new x value for the vector.
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
|
+
set x(x: number);
|
|
14
|
+
/**
|
|
15
|
+
* Sets the y component of the vector and notifies any registered callbacks.
|
|
16
|
+
* @param y - The new y value for the vector.
|
|
17
|
+
*/
|
|
18
|
+
set y(y: number);
|
|
19
|
+
get x(): number;
|
|
20
|
+
get y(): number;
|
|
13
21
|
/**
|
|
14
22
|
* Adds another vector to this vector
|
|
15
23
|
* @param vector - The vector to add
|
|
@@ -159,7 +167,7 @@ declare const TWO_PI: number;
|
|
|
159
167
|
|
|
160
168
|
declare class Camera extends Node {
|
|
161
169
|
zoom: number;
|
|
162
|
-
constructor(
|
|
170
|
+
constructor(zoom?: number);
|
|
163
171
|
update(deltaTime: number): void;
|
|
164
172
|
transformCoordinates(position: Vector2D): Vector2D;
|
|
165
173
|
}
|
|
@@ -169,8 +177,10 @@ declare class InputManager extends Node {
|
|
|
169
177
|
private keyJustPressed;
|
|
170
178
|
private mouseState;
|
|
171
179
|
private mouseJustPressed;
|
|
180
|
+
mousePos: Vector2D;
|
|
172
181
|
constructor();
|
|
173
182
|
private setupListeners;
|
|
183
|
+
private handleMouseMove;
|
|
174
184
|
private handleKeyDown;
|
|
175
185
|
private handleKeyUp;
|
|
176
186
|
private handleMouseDown;
|
|
@@ -208,18 +218,24 @@ declare class Scene extends Node {
|
|
|
208
218
|
interface NodeConfig {
|
|
209
219
|
id?: string;
|
|
210
220
|
pos?: Vector2D;
|
|
221
|
+
scene?: Scene;
|
|
211
222
|
}
|
|
212
223
|
declare class Node {
|
|
213
|
-
id: string;
|
|
214
224
|
pos: Vector2D;
|
|
225
|
+
id: string;
|
|
215
226
|
children: Node[];
|
|
216
227
|
scene?: Scene;
|
|
217
|
-
constructor(config?: NodeConfig);
|
|
228
|
+
constructor(scene?: Scene, config?: NodeConfig);
|
|
218
229
|
addObject(object: Node): void;
|
|
219
230
|
removeObject(object: Node): void;
|
|
220
231
|
private generateID;
|
|
221
232
|
}
|
|
222
233
|
|
|
234
|
+
declare abstract class BoundingBox extends Node {
|
|
235
|
+
abstract checkCollision(other: BoundingBox): boolean;
|
|
236
|
+
abstract isPointInside(_point: Vector2D): boolean;
|
|
237
|
+
}
|
|
238
|
+
|
|
223
239
|
interface CircleConfig {
|
|
224
240
|
vel?: Vector2D;
|
|
225
241
|
size?: number;
|
|
@@ -230,10 +246,18 @@ declare class Circle extends Node {
|
|
|
230
246
|
vel: Vector2D;
|
|
231
247
|
size: number;
|
|
232
248
|
friction: number;
|
|
233
|
-
|
|
249
|
+
boundingBox: BoundingBox;
|
|
250
|
+
constructor(scene?: Scene, config?: CircleConfig);
|
|
234
251
|
draw(ctx: CanvasRenderingContext2D, selected?: boolean): void;
|
|
235
252
|
}
|
|
236
253
|
|
|
254
|
+
declare class CircleBoundingBox extends BoundingBox {
|
|
255
|
+
radius: number;
|
|
256
|
+
constructor(scene?: Scene, radius?: number);
|
|
257
|
+
checkCollision(other: BoundingBox): boolean;
|
|
258
|
+
isPointInside(_point: Vector2D): boolean;
|
|
259
|
+
}
|
|
260
|
+
|
|
237
261
|
declare function getCanvas(id: string): HTMLCanvasElement;
|
|
238
262
|
|
|
239
|
-
export { Camera, Circle, type CircleConfig, type Drawable, Node, type NodeConfig, Scene, type SceneOptions, TWO_PI, type Updatable, Vector2D, getCanvas };
|
|
263
|
+
export { BoundingBox, Camera, Circle, CircleBoundingBox, type CircleConfig, type Drawable, Node, type NodeConfig, Scene, type SceneOptions, TWO_PI, type Updatable, Vector2D, getCanvas };
|
package/dist/main.js
CHANGED
|
@@ -20,10 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/main.ts
|
|
21
21
|
var main_exports = {};
|
|
22
22
|
__export(main_exports, {
|
|
23
|
+
BoundingBox: () => BoundingBox,
|
|
23
24
|
Camera: () => Camera,
|
|
24
25
|
Circle: () => Circle,
|
|
26
|
+
CircleBoundingBox: () => CircleBoundingBox,
|
|
25
27
|
Node: () => Node,
|
|
26
|
-
Scene: () =>
|
|
28
|
+
Scene: () => Scene2,
|
|
27
29
|
TWO_PI: () => TWO_PI,
|
|
28
30
|
Vector2D: () => Vector2D,
|
|
29
31
|
getCanvas: () => getCanvas
|
|
@@ -35,14 +37,39 @@ var TWO_PI = Math.PI * 2;
|
|
|
35
37
|
|
|
36
38
|
// src/classes/Vector2D.ts
|
|
37
39
|
var Vector2D = class _Vector2D {
|
|
40
|
+
_x = 0;
|
|
41
|
+
_y = 0;
|
|
42
|
+
constructor(x = 0, y = 0) {
|
|
43
|
+
this._x = x;
|
|
44
|
+
this._y = y;
|
|
45
|
+
}
|
|
46
|
+
onChange = [];
|
|
38
47
|
/**
|
|
39
|
-
*
|
|
40
|
-
* @param x - The x
|
|
41
|
-
* @param y - The y component of the vector
|
|
48
|
+
* Sets the x component of the vector and notifies any registered callbacks.
|
|
49
|
+
* @param x - The new x value for the vector.
|
|
42
50
|
*/
|
|
43
|
-
|
|
44
|
-
this.
|
|
45
|
-
this.
|
|
51
|
+
set x(x) {
|
|
52
|
+
const d = new _Vector2D(x - this._x, this.y - this._y);
|
|
53
|
+
for (const callback of this.onChange) {
|
|
54
|
+
callback(d);
|
|
55
|
+
}
|
|
56
|
+
this._x = x;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Sets the y component of the vector and notifies any registered callbacks.
|
|
60
|
+
* @param y - The new y value for the vector.
|
|
61
|
+
*/
|
|
62
|
+
set y(y) {
|
|
63
|
+
for (const callback of this.onChange) {
|
|
64
|
+
callback(new _Vector2D(this.x - this._x, y - this._y));
|
|
65
|
+
}
|
|
66
|
+
this._y = y;
|
|
67
|
+
}
|
|
68
|
+
get x() {
|
|
69
|
+
return this._x;
|
|
70
|
+
}
|
|
71
|
+
get y() {
|
|
72
|
+
return this._y;
|
|
46
73
|
}
|
|
47
74
|
/**
|
|
48
75
|
* Adds another vector to this vector
|
|
@@ -265,17 +292,24 @@ var Vector2D = class _Vector2D {
|
|
|
265
292
|
// src/nodes/Node.ts
|
|
266
293
|
var import_uuid = require("uuid");
|
|
267
294
|
var Node = class {
|
|
268
|
-
id;
|
|
269
295
|
pos;
|
|
296
|
+
id;
|
|
270
297
|
children = [];
|
|
271
298
|
scene;
|
|
272
|
-
constructor(config) {
|
|
299
|
+
constructor(scene, config) {
|
|
300
|
+
this.scene = scene;
|
|
273
301
|
const { id, pos } = config || {};
|
|
274
302
|
this.id = id || this.generateID();
|
|
275
303
|
this.pos = pos || new Vector2D();
|
|
304
|
+
this.pos.onChange.push((delta) => {
|
|
305
|
+
for (const child of this.children) {
|
|
306
|
+
child.pos = child.pos.add(delta);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
276
309
|
}
|
|
277
310
|
addObject(object) {
|
|
278
311
|
this.children.push(object);
|
|
312
|
+
if (!object.scene) object.scene = this.scene;
|
|
279
313
|
}
|
|
280
314
|
removeObject(object) {
|
|
281
315
|
const index = this.children.indexOf(object);
|
|
@@ -288,25 +322,76 @@ var Node = class {
|
|
|
288
322
|
}
|
|
289
323
|
};
|
|
290
324
|
|
|
325
|
+
// src/nodes/BoundingBox.ts
|
|
326
|
+
var BoundingBox = class extends Node {
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// src/nodes/Camera.ts
|
|
330
|
+
var Camera = class extends Node {
|
|
331
|
+
zoom;
|
|
332
|
+
constructor(zoom = 1) {
|
|
333
|
+
super();
|
|
334
|
+
this.zoom = zoom;
|
|
335
|
+
}
|
|
336
|
+
update(deltaTime) {
|
|
337
|
+
}
|
|
338
|
+
transformCoordinates(position) {
|
|
339
|
+
return new Vector2D((position.x - this.pos.x) * this.zoom, (position.y - this.pos.y) * this.zoom);
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
// src/nodes/CircleBoundingBox.ts
|
|
344
|
+
var CircleBoundingBox = class _CircleBoundingBox extends BoundingBox {
|
|
345
|
+
radius;
|
|
346
|
+
constructor(scene, radius) {
|
|
347
|
+
super(scene);
|
|
348
|
+
this.radius = radius || 10;
|
|
349
|
+
}
|
|
350
|
+
checkCollision(other) {
|
|
351
|
+
if (other instanceof _CircleBoundingBox) {
|
|
352
|
+
const thisPoint = this.scene?.camera.transformCoordinates(new Vector2D(this.pos.x, this.pos.y));
|
|
353
|
+
const otherPoint = this.scene?.camera.transformCoordinates(new Vector2D(other.pos.x, other.pos.y));
|
|
354
|
+
if (!thisPoint || !otherPoint) return false;
|
|
355
|
+
const dx = thisPoint.x - otherPoint.x;
|
|
356
|
+
const dy = thisPoint.y - otherPoint.y;
|
|
357
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
358
|
+
return distance < this.radius + other.radius;
|
|
359
|
+
}
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
isPointInside(_point) {
|
|
363
|
+
const point = this.scene?.camera.transformCoordinates(_point);
|
|
364
|
+
if (!point) return false;
|
|
365
|
+
const dx = this.pos.x - point.x;
|
|
366
|
+
const dy = this.pos.y - point.y;
|
|
367
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
368
|
+
return distance < this.radius;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
|
|
291
372
|
// src/nodes/Circle.ts
|
|
292
373
|
var Circle = class extends Node {
|
|
293
374
|
vel = new Vector2D();
|
|
294
375
|
size = 10;
|
|
295
376
|
friction = 0.1;
|
|
296
|
-
|
|
297
|
-
|
|
377
|
+
boundingBox = new CircleBoundingBox(this.scene, this.size);
|
|
378
|
+
constructor(scene, config) {
|
|
379
|
+
super(scene);
|
|
298
380
|
this.vel = config?.vel || new Vector2D();
|
|
299
381
|
this.size = config?.size || 10;
|
|
300
382
|
this.friction = config?.friction || 0.1;
|
|
383
|
+
if (config?.startsWithBoundingBox) {
|
|
384
|
+
this.boundingBox = new CircleBoundingBox(scene, this.size);
|
|
385
|
+
this.addObject(this.boundingBox);
|
|
386
|
+
}
|
|
301
387
|
}
|
|
302
388
|
draw(ctx, selected) {
|
|
303
|
-
const radius = 10;
|
|
304
389
|
const cameraPos = this.scene?.camera.pos || new Vector2D();
|
|
305
390
|
const cameraScale = this.scene?.camera.zoom || 1;
|
|
306
391
|
const relativePos = new Vector2D((this.pos.x - cameraPos.x) * cameraScale, (this.pos.y - cameraPos.y) * cameraScale);
|
|
307
392
|
if (selected) {
|
|
308
393
|
ctx.beginPath();
|
|
309
|
-
ctx.arc(relativePos.x, relativePos.y,
|
|
394
|
+
ctx.arc(relativePos.x, relativePos.y, this.size + 5, 0, Math.PI * 2);
|
|
310
395
|
ctx.fillStyle = "transparent";
|
|
311
396
|
ctx.lineWidth = 3;
|
|
312
397
|
ctx.strokeStyle = "white";
|
|
@@ -314,33 +399,20 @@ var Circle = class extends Node {
|
|
|
314
399
|
ctx.closePath();
|
|
315
400
|
}
|
|
316
401
|
ctx.beginPath();
|
|
317
|
-
ctx.arc(relativePos.x, relativePos.y,
|
|
402
|
+
ctx.arc(relativePos.x, relativePos.y, this.size, 0, Math.PI * 2);
|
|
318
403
|
ctx.fillStyle = "blue";
|
|
319
404
|
ctx.fill();
|
|
320
405
|
ctx.closePath();
|
|
321
406
|
}
|
|
322
407
|
};
|
|
323
408
|
|
|
324
|
-
// src/nodes/Camera.ts
|
|
325
|
-
var Camera = class extends Node {
|
|
326
|
-
zoom;
|
|
327
|
-
constructor(x = 0, y = 0, zoom = 1) {
|
|
328
|
-
super();
|
|
329
|
-
this.zoom = zoom;
|
|
330
|
-
}
|
|
331
|
-
update(deltaTime) {
|
|
332
|
-
}
|
|
333
|
-
transformCoordinates(position) {
|
|
334
|
-
return new Vector2D((position.x - this.pos.x) * this.zoom, (position.y - this.pos.y) * this.zoom);
|
|
335
|
-
}
|
|
336
|
-
};
|
|
337
|
-
|
|
338
409
|
// src/nodes/InputManager.ts
|
|
339
410
|
var InputManager = class extends Node {
|
|
340
411
|
keyState = /* @__PURE__ */ new Map();
|
|
341
412
|
keyJustPressed = /* @__PURE__ */ new Set();
|
|
342
413
|
mouseState = /* @__PURE__ */ new Map();
|
|
343
414
|
mouseJustPressed = /* @__PURE__ */ new Set();
|
|
415
|
+
mousePos = new Vector2D();
|
|
344
416
|
constructor() {
|
|
345
417
|
super();
|
|
346
418
|
this.setupListeners();
|
|
@@ -350,6 +422,10 @@ var InputManager = class extends Node {
|
|
|
350
422
|
window.addEventListener("keyup", this.handleKeyUp.bind(this));
|
|
351
423
|
window.addEventListener("mousedown", this.handleMouseDown.bind(this));
|
|
352
424
|
window.addEventListener("mouseup", this.handleMouseUp.bind(this));
|
|
425
|
+
window.addEventListener("mousemove", this.handleMouseMove.bind(this));
|
|
426
|
+
}
|
|
427
|
+
handleMouseMove(event) {
|
|
428
|
+
this.mousePos = new Vector2D(event.clientX, event.clientY);
|
|
353
429
|
}
|
|
354
430
|
handleKeyDown(event) {
|
|
355
431
|
const key = event.key;
|
|
@@ -398,7 +474,7 @@ var InputManager = class extends Node {
|
|
|
398
474
|
};
|
|
399
475
|
|
|
400
476
|
// src/nodes/Scene.ts
|
|
401
|
-
var
|
|
477
|
+
var Scene2 = class extends Node {
|
|
402
478
|
camera;
|
|
403
479
|
inputManager;
|
|
404
480
|
ctx;
|
|
@@ -412,8 +488,8 @@ var Scene = class extends Node {
|
|
|
412
488
|
this.setup();
|
|
413
489
|
}
|
|
414
490
|
addObject(object) {
|
|
415
|
-
super.addObject(object);
|
|
416
491
|
object.scene = this;
|
|
492
|
+
super.addObject(object);
|
|
417
493
|
}
|
|
418
494
|
setup() {
|
|
419
495
|
this.resizeCanvas();
|
|
@@ -487,8 +563,10 @@ function getCanvas(id) {
|
|
|
487
563
|
}
|
|
488
564
|
// Annotate the CommonJS export names for ESM import in node:
|
|
489
565
|
0 && (module.exports = {
|
|
566
|
+
BoundingBox,
|
|
490
567
|
Camera,
|
|
491
568
|
Circle,
|
|
569
|
+
CircleBoundingBox,
|
|
492
570
|
Node,
|
|
493
571
|
Scene,
|
|
494
572
|
TWO_PI,
|
package/dist/main.mjs
CHANGED
|
@@ -3,14 +3,39 @@ var TWO_PI = Math.PI * 2;
|
|
|
3
3
|
|
|
4
4
|
// src/classes/Vector2D.ts
|
|
5
5
|
var Vector2D = class _Vector2D {
|
|
6
|
+
_x = 0;
|
|
7
|
+
_y = 0;
|
|
8
|
+
constructor(x = 0, y = 0) {
|
|
9
|
+
this._x = x;
|
|
10
|
+
this._y = y;
|
|
11
|
+
}
|
|
12
|
+
onChange = [];
|
|
6
13
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @param x - The x
|
|
9
|
-
* @param y - The y component of the vector
|
|
14
|
+
* Sets the x component of the vector and notifies any registered callbacks.
|
|
15
|
+
* @param x - The new x value for the vector.
|
|
10
16
|
*/
|
|
11
|
-
|
|
12
|
-
this.
|
|
13
|
-
this.
|
|
17
|
+
set x(x) {
|
|
18
|
+
const d = new _Vector2D(x - this._x, this.y - this._y);
|
|
19
|
+
for (const callback of this.onChange) {
|
|
20
|
+
callback(d);
|
|
21
|
+
}
|
|
22
|
+
this._x = x;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Sets the y component of the vector and notifies any registered callbacks.
|
|
26
|
+
* @param y - The new y value for the vector.
|
|
27
|
+
*/
|
|
28
|
+
set y(y) {
|
|
29
|
+
for (const callback of this.onChange) {
|
|
30
|
+
callback(new _Vector2D(this.x - this._x, y - this._y));
|
|
31
|
+
}
|
|
32
|
+
this._y = y;
|
|
33
|
+
}
|
|
34
|
+
get x() {
|
|
35
|
+
return this._x;
|
|
36
|
+
}
|
|
37
|
+
get y() {
|
|
38
|
+
return this._y;
|
|
14
39
|
}
|
|
15
40
|
/**
|
|
16
41
|
* Adds another vector to this vector
|
|
@@ -233,17 +258,24 @@ var Vector2D = class _Vector2D {
|
|
|
233
258
|
// src/nodes/Node.ts
|
|
234
259
|
import { v4 as uuidv4 } from "uuid";
|
|
235
260
|
var Node = class {
|
|
236
|
-
id;
|
|
237
261
|
pos;
|
|
262
|
+
id;
|
|
238
263
|
children = [];
|
|
239
264
|
scene;
|
|
240
|
-
constructor(config) {
|
|
265
|
+
constructor(scene, config) {
|
|
266
|
+
this.scene = scene;
|
|
241
267
|
const { id, pos } = config || {};
|
|
242
268
|
this.id = id || this.generateID();
|
|
243
269
|
this.pos = pos || new Vector2D();
|
|
270
|
+
this.pos.onChange.push((delta) => {
|
|
271
|
+
for (const child of this.children) {
|
|
272
|
+
child.pos = child.pos.add(delta);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
244
275
|
}
|
|
245
276
|
addObject(object) {
|
|
246
277
|
this.children.push(object);
|
|
278
|
+
if (!object.scene) object.scene = this.scene;
|
|
247
279
|
}
|
|
248
280
|
removeObject(object) {
|
|
249
281
|
const index = this.children.indexOf(object);
|
|
@@ -256,25 +288,76 @@ var Node = class {
|
|
|
256
288
|
}
|
|
257
289
|
};
|
|
258
290
|
|
|
291
|
+
// src/nodes/BoundingBox.ts
|
|
292
|
+
var BoundingBox = class extends Node {
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// src/nodes/Camera.ts
|
|
296
|
+
var Camera = class extends Node {
|
|
297
|
+
zoom;
|
|
298
|
+
constructor(zoom = 1) {
|
|
299
|
+
super();
|
|
300
|
+
this.zoom = zoom;
|
|
301
|
+
}
|
|
302
|
+
update(deltaTime) {
|
|
303
|
+
}
|
|
304
|
+
transformCoordinates(position) {
|
|
305
|
+
return new Vector2D((position.x - this.pos.x) * this.zoom, (position.y - this.pos.y) * this.zoom);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
// src/nodes/CircleBoundingBox.ts
|
|
310
|
+
var CircleBoundingBox = class _CircleBoundingBox extends BoundingBox {
|
|
311
|
+
radius;
|
|
312
|
+
constructor(scene, radius) {
|
|
313
|
+
super(scene);
|
|
314
|
+
this.radius = radius || 10;
|
|
315
|
+
}
|
|
316
|
+
checkCollision(other) {
|
|
317
|
+
if (other instanceof _CircleBoundingBox) {
|
|
318
|
+
const thisPoint = this.scene?.camera.transformCoordinates(new Vector2D(this.pos.x, this.pos.y));
|
|
319
|
+
const otherPoint = this.scene?.camera.transformCoordinates(new Vector2D(other.pos.x, other.pos.y));
|
|
320
|
+
if (!thisPoint || !otherPoint) return false;
|
|
321
|
+
const dx = thisPoint.x - otherPoint.x;
|
|
322
|
+
const dy = thisPoint.y - otherPoint.y;
|
|
323
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
324
|
+
return distance < this.radius + other.radius;
|
|
325
|
+
}
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
isPointInside(_point) {
|
|
329
|
+
const point = this.scene?.camera.transformCoordinates(_point);
|
|
330
|
+
if (!point) return false;
|
|
331
|
+
const dx = this.pos.x - point.x;
|
|
332
|
+
const dy = this.pos.y - point.y;
|
|
333
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
334
|
+
return distance < this.radius;
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
|
|
259
338
|
// src/nodes/Circle.ts
|
|
260
339
|
var Circle = class extends Node {
|
|
261
340
|
vel = new Vector2D();
|
|
262
341
|
size = 10;
|
|
263
342
|
friction = 0.1;
|
|
264
|
-
|
|
265
|
-
|
|
343
|
+
boundingBox = new CircleBoundingBox(this.scene, this.size);
|
|
344
|
+
constructor(scene, config) {
|
|
345
|
+
super(scene);
|
|
266
346
|
this.vel = config?.vel || new Vector2D();
|
|
267
347
|
this.size = config?.size || 10;
|
|
268
348
|
this.friction = config?.friction || 0.1;
|
|
349
|
+
if (config?.startsWithBoundingBox) {
|
|
350
|
+
this.boundingBox = new CircleBoundingBox(scene, this.size);
|
|
351
|
+
this.addObject(this.boundingBox);
|
|
352
|
+
}
|
|
269
353
|
}
|
|
270
354
|
draw(ctx, selected) {
|
|
271
|
-
const radius = 10;
|
|
272
355
|
const cameraPos = this.scene?.camera.pos || new Vector2D();
|
|
273
356
|
const cameraScale = this.scene?.camera.zoom || 1;
|
|
274
357
|
const relativePos = new Vector2D((this.pos.x - cameraPos.x) * cameraScale, (this.pos.y - cameraPos.y) * cameraScale);
|
|
275
358
|
if (selected) {
|
|
276
359
|
ctx.beginPath();
|
|
277
|
-
ctx.arc(relativePos.x, relativePos.y,
|
|
360
|
+
ctx.arc(relativePos.x, relativePos.y, this.size + 5, 0, Math.PI * 2);
|
|
278
361
|
ctx.fillStyle = "transparent";
|
|
279
362
|
ctx.lineWidth = 3;
|
|
280
363
|
ctx.strokeStyle = "white";
|
|
@@ -282,33 +365,20 @@ var Circle = class extends Node {
|
|
|
282
365
|
ctx.closePath();
|
|
283
366
|
}
|
|
284
367
|
ctx.beginPath();
|
|
285
|
-
ctx.arc(relativePos.x, relativePos.y,
|
|
368
|
+
ctx.arc(relativePos.x, relativePos.y, this.size, 0, Math.PI * 2);
|
|
286
369
|
ctx.fillStyle = "blue";
|
|
287
370
|
ctx.fill();
|
|
288
371
|
ctx.closePath();
|
|
289
372
|
}
|
|
290
373
|
};
|
|
291
374
|
|
|
292
|
-
// src/nodes/Camera.ts
|
|
293
|
-
var Camera = class extends Node {
|
|
294
|
-
zoom;
|
|
295
|
-
constructor(x = 0, y = 0, zoom = 1) {
|
|
296
|
-
super();
|
|
297
|
-
this.zoom = zoom;
|
|
298
|
-
}
|
|
299
|
-
update(deltaTime) {
|
|
300
|
-
}
|
|
301
|
-
transformCoordinates(position) {
|
|
302
|
-
return new Vector2D((position.x - this.pos.x) * this.zoom, (position.y - this.pos.y) * this.zoom);
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
|
|
306
375
|
// src/nodes/InputManager.ts
|
|
307
376
|
var InputManager = class extends Node {
|
|
308
377
|
keyState = /* @__PURE__ */ new Map();
|
|
309
378
|
keyJustPressed = /* @__PURE__ */ new Set();
|
|
310
379
|
mouseState = /* @__PURE__ */ new Map();
|
|
311
380
|
mouseJustPressed = /* @__PURE__ */ new Set();
|
|
381
|
+
mousePos = new Vector2D();
|
|
312
382
|
constructor() {
|
|
313
383
|
super();
|
|
314
384
|
this.setupListeners();
|
|
@@ -318,6 +388,10 @@ var InputManager = class extends Node {
|
|
|
318
388
|
window.addEventListener("keyup", this.handleKeyUp.bind(this));
|
|
319
389
|
window.addEventListener("mousedown", this.handleMouseDown.bind(this));
|
|
320
390
|
window.addEventListener("mouseup", this.handleMouseUp.bind(this));
|
|
391
|
+
window.addEventListener("mousemove", this.handleMouseMove.bind(this));
|
|
392
|
+
}
|
|
393
|
+
handleMouseMove(event) {
|
|
394
|
+
this.mousePos = new Vector2D(event.clientX, event.clientY);
|
|
321
395
|
}
|
|
322
396
|
handleKeyDown(event) {
|
|
323
397
|
const key = event.key;
|
|
@@ -366,7 +440,7 @@ var InputManager = class extends Node {
|
|
|
366
440
|
};
|
|
367
441
|
|
|
368
442
|
// src/nodes/Scene.ts
|
|
369
|
-
var
|
|
443
|
+
var Scene2 = class extends Node {
|
|
370
444
|
camera;
|
|
371
445
|
inputManager;
|
|
372
446
|
ctx;
|
|
@@ -380,8 +454,8 @@ var Scene = class extends Node {
|
|
|
380
454
|
this.setup();
|
|
381
455
|
}
|
|
382
456
|
addObject(object) {
|
|
383
|
-
super.addObject(object);
|
|
384
457
|
object.scene = this;
|
|
458
|
+
super.addObject(object);
|
|
385
459
|
}
|
|
386
460
|
setup() {
|
|
387
461
|
this.resizeCanvas();
|
|
@@ -454,10 +528,12 @@ function getCanvas(id) {
|
|
|
454
528
|
return canvas;
|
|
455
529
|
}
|
|
456
530
|
export {
|
|
531
|
+
BoundingBox,
|
|
457
532
|
Camera,
|
|
458
533
|
Circle,
|
|
534
|
+
CircleBoundingBox,
|
|
459
535
|
Node,
|
|
460
|
-
Scene,
|
|
536
|
+
Scene2 as Scene,
|
|
461
537
|
TWO_PI,
|
|
462
538
|
Vector2D,
|
|
463
539
|
getCanvas
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jiant/canvable",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "A tool for building canvas apps",
|
|
5
5
|
"main": "./dist/main.js",
|
|
6
6
|
"module": "./dist/main.mjs",
|
|
@@ -27,6 +27,10 @@
|
|
|
27
27
|
"drawing",
|
|
28
28
|
"visualization"
|
|
29
29
|
],
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/SrDouglax/Canvable.git"
|
|
33
|
+
},
|
|
30
34
|
"publishConfig": {
|
|
31
35
|
"access": "public"
|
|
32
36
|
}
|