@guinetik/gcanvas 1.0.2 → 1.0.4
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/gcanvas.es.js +25656 -0
- package/dist/gcanvas.es.min.js +1 -0
- package/dist/gcanvas.umd.js +1 -0
- package/dist/gcanvas.umd.min.js +1 -0
- package/package.json +23 -6
- package/src/game/objects/index.js +1 -0
- package/src/game/objects/spritesheet.js +260 -0
- package/src/game/ui/theme.js +6 -0
- package/src/io/keys.js +9 -1
- package/src/math/boolean.js +481 -0
- package/src/math/index.js +1 -0
- package/.github/workflows/release.yaml +0 -70
- package/.jshintrc +0 -4
- package/.vscode/settings.json +0 -22
- package/CLAUDE.md +0 -310
- package/blackhole.jpg +0 -0
- package/demo.png +0 -0
- package/demos/CNAME +0 -1
- package/demos/animations.html +0 -31
- package/demos/basic.html +0 -38
- package/demos/baskara.html +0 -31
- package/demos/bezier.html +0 -35
- package/demos/beziersignature.html +0 -29
- package/demos/blackhole.html +0 -28
- package/demos/blob.html +0 -35
- package/demos/coordinates.html +0 -698
- package/demos/cube3d.html +0 -23
- package/demos/demos.css +0 -303
- package/demos/dino.html +0 -42
- package/demos/easing.html +0 -28
- package/demos/events.html +0 -195
- package/demos/fluent.html +0 -647
- package/demos/fluid-simple.html +0 -22
- package/demos/fluid.html +0 -37
- package/demos/fractals.html +0 -36
- package/demos/gameobjects.html +0 -626
- package/demos/genart.html +0 -26
- package/demos/gendream.html +0 -26
- package/demos/group.html +0 -36
- package/demos/home.html +0 -587
- package/demos/index.html +0 -376
- package/demos/isometric.html +0 -34
- package/demos/js/animations.js +0 -452
- package/demos/js/basic.js +0 -204
- package/demos/js/baskara.js +0 -751
- package/demos/js/bezier.js +0 -692
- package/demos/js/beziersignature.js +0 -241
- package/demos/js/blackhole/accretiondisk.obj.js +0 -379
- package/demos/js/blackhole/blackhole.obj.js +0 -318
- package/demos/js/blackhole/index.js +0 -409
- package/demos/js/blackhole/particle.js +0 -56
- package/demos/js/blackhole/starfield.obj.js +0 -218
- package/demos/js/blob.js +0 -2276
- package/demos/js/coordinates.js +0 -840
- package/demos/js/cube3d.js +0 -789
- package/demos/js/dino.js +0 -1420
- package/demos/js/easing.js +0 -477
- package/demos/js/fluent.js +0 -183
- package/demos/js/fluid-simple.js +0 -253
- package/demos/js/fluid.js +0 -527
- package/demos/js/fractals.js +0 -931
- package/demos/js/fractalworker.js +0 -93
- package/demos/js/gameobjects.js +0 -176
- package/demos/js/genart.js +0 -268
- package/demos/js/gendream.js +0 -209
- package/demos/js/group.js +0 -140
- package/demos/js/info-toggle.js +0 -25
- package/demos/js/isometric.js +0 -863
- package/demos/js/kerr.js +0 -1556
- package/demos/js/lavalamp.js +0 -590
- package/demos/js/layout.js +0 -354
- package/demos/js/mondrian.js +0 -285
- package/demos/js/opacity.js +0 -275
- package/demos/js/painter.js +0 -484
- package/demos/js/particles-showcase.js +0 -514
- package/demos/js/particles.js +0 -299
- package/demos/js/patterns.js +0 -397
- package/demos/js/penrose/artifact.js +0 -69
- package/demos/js/penrose/blackhole.js +0 -121
- package/demos/js/penrose/constants.js +0 -73
- package/demos/js/penrose/game.js +0 -943
- package/demos/js/penrose/lore.js +0 -278
- package/demos/js/penrose/penrosescene.js +0 -892
- package/demos/js/penrose/ship.js +0 -216
- package/demos/js/penrose/sounds.js +0 -211
- package/demos/js/penrose/voidparticle.js +0 -55
- package/demos/js/penrose/voidscene.js +0 -258
- package/demos/js/penrose/voidship.js +0 -144
- package/demos/js/penrose/wormhole.js +0 -46
- package/demos/js/pipeline.js +0 -555
- package/demos/js/plane3d.js +0 -256
- package/demos/js/platformer.js +0 -1579
- package/demos/js/scene.js +0 -304
- package/demos/js/scenes.js +0 -320
- package/demos/js/schrodinger.js +0 -410
- package/demos/js/schwarzschild.js +0 -1023
- package/demos/js/shapes.js +0 -628
- package/demos/js/space/alien.js +0 -171
- package/demos/js/space/boom.js +0 -98
- package/demos/js/space/boss.js +0 -353
- package/demos/js/space/buff.js +0 -73
- package/demos/js/space/bullet.js +0 -102
- package/demos/js/space/constants.js +0 -85
- package/demos/js/space/game.js +0 -1884
- package/demos/js/space/hud.js +0 -112
- package/demos/js/space/laserbeam.js +0 -179
- package/demos/js/space/lightning.js +0 -277
- package/demos/js/space/minion.js +0 -192
- package/demos/js/space/missile.js +0 -212
- package/demos/js/space/player.js +0 -430
- package/demos/js/space/powerup.js +0 -90
- package/demos/js/space/starfield.js +0 -58
- package/demos/js/space/starpower.js +0 -90
- package/demos/js/spacetime.js +0 -559
- package/demos/js/sphere3d.js +0 -229
- package/demos/js/sprite.js +0 -473
- package/demos/js/svgtween.js +0 -204
- package/demos/js/tde/accretiondisk.js +0 -471
- package/demos/js/tde/blackhole.js +0 -219
- package/demos/js/tde/blackholescene.js +0 -209
- package/demos/js/tde/config.js +0 -59
- package/demos/js/tde/index.js +0 -820
- package/demos/js/tde/jets.js +0 -290
- package/demos/js/tde/lensedstarfield.js +0 -154
- package/demos/js/tde/tdestar.js +0 -297
- package/demos/js/tde/tidalstream.js +0 -372
- package/demos/js/tde_old/blackhole.obj.js +0 -354
- package/demos/js/tde_old/debris.obj.js +0 -791
- package/demos/js/tde_old/flare.obj.js +0 -239
- package/demos/js/tde_old/index.js +0 -448
- package/demos/js/tde_old/star.obj.js +0 -812
- package/demos/js/tiles.js +0 -312
- package/demos/js/tweendemo.js +0 -79
- package/demos/js/visibility.js +0 -102
- package/demos/kerr.html +0 -28
- package/demos/lavalamp.html +0 -27
- package/demos/layouts.html +0 -37
- package/demos/logo.svg +0 -4
- package/demos/loop.html +0 -84
- package/demos/mondrian.html +0 -32
- package/demos/og_image.png +0 -0
- package/demos/opacity.html +0 -36
- package/demos/painter.html +0 -39
- package/demos/particles-showcase.html +0 -28
- package/demos/particles.html +0 -24
- package/demos/patterns.html +0 -33
- package/demos/penrose-game.html +0 -31
- package/demos/pipeline.html +0 -737
- package/demos/plane3d.html +0 -24
- package/demos/platformer.html +0 -43
- package/demos/scene.html +0 -33
- package/demos/scenes.html +0 -96
- package/demos/schrodinger.html +0 -27
- package/demos/schwarzschild.html +0 -27
- package/demos/shapes.html +0 -16
- package/demos/space.html +0 -85
- package/demos/spacetime.html +0 -27
- package/demos/sphere3d.html +0 -24
- package/demos/sprite.html +0 -18
- package/demos/svgtween.html +0 -29
- package/demos/tde.html +0 -28
- package/demos/tiles.html +0 -28
- package/demos/transforms.html +0 -400
- package/demos/tween.html +0 -45
- package/demos/visibility.html +0 -33
- package/docs/README.md +0 -230
- package/docs/api/FluidSystem.md +0 -173
- package/docs/concepts/architecture-overview.md +0 -204
- package/docs/concepts/coordinate-system.md +0 -384
- package/docs/concepts/lifecycle.md +0 -255
- package/docs/concepts/rendering-pipeline.md +0 -279
- package/docs/concepts/shapes-vs-gameobjects.md +0 -187
- package/docs/concepts/tde-zorder.md +0 -106
- package/docs/concepts/two-layer-architecture.md +0 -229
- package/docs/fluid-dynamics.md +0 -99
- package/docs/getting-started/first-game.md +0 -354
- package/docs/getting-started/hello-world.md +0 -269
- package/docs/getting-started/installation.md +0 -175
- package/docs/modules/collision/README.md +0 -453
- package/docs/modules/fluent/README.md +0 -1075
- package/docs/modules/game/README.md +0 -303
- package/docs/modules/isometric-camera.md +0 -210
- package/docs/modules/isometric.md +0 -275
- package/docs/modules/painter/README.md +0 -328
- package/docs/modules/particle/README.md +0 -559
- package/docs/modules/shapes/README.md +0 -221
- package/docs/modules/shapes/base/euclidian.md +0 -123
- package/docs/modules/shapes/base/geometry2d.md +0 -204
- package/docs/modules/shapes/base/renderable.md +0 -215
- package/docs/modules/shapes/base/shape.md +0 -262
- package/docs/modules/shapes/base/transformable.md +0 -243
- package/docs/modules/shapes/hierarchy.md +0 -218
- package/docs/modules/state/README.md +0 -577
- package/docs/modules/util/README.md +0 -99
- package/docs/modules/util/camera3d.md +0 -412
- package/docs/modules/util/scene3d.md +0 -395
- package/index.html +0 -17
- package/jsdoc.json +0 -50
- package/scripts/build-demo.js +0 -69
- package/scripts/bundle4llm.js +0 -276
- package/scripts/clearconsole.js +0 -48
- package/test/math/orbital.test.js +0 -61
- package/test/math/tensor.test.js +0 -114
- package/test/particle/emitter.test.js +0 -204
- package/test/particle/particle-system.test.js +0 -310
- package/test/particle/particle.test.js +0 -116
- package/test/particle/updaters.test.js +0 -386
- package/test/setup.js +0 -120
- package/test/shapes/euclidian.test.js +0 -44
- package/test/shapes/geometry.test.js +0 -86
- package/test/shapes/group.test.js +0 -86
- package/test/shapes/rectangle.test.js +0 -64
- package/test/shapes/transform.test.js +0 -379
- package/test/util/camera3d.test.js +0 -428
- package/test/util/scene3d.test.js +0 -352
- package/vite.config.js +0 -50
- package/vitest.config.js +0 -13
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
-
import { Scene3D } from "../../src/game/objects/scene3d";
|
|
3
|
-
import { Camera3D } from "../../src/util/camera3d";
|
|
4
|
-
import { Painter } from "../../src/painter/painter";
|
|
5
|
-
|
|
6
|
-
// Mock game object
|
|
7
|
-
const createMockGame = () => ({
|
|
8
|
-
width: 800,
|
|
9
|
-
height: 600,
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
// Mock child game object
|
|
13
|
-
const createMockChild = (options = {}) => ({
|
|
14
|
-
x: options.x ?? 0,
|
|
15
|
-
y: options.y ?? 0,
|
|
16
|
-
z: options.z ?? undefined,
|
|
17
|
-
visible: options.visible ?? true,
|
|
18
|
-
draw: vi.fn(),
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe("Scene3D", () => {
|
|
22
|
-
let mockGame;
|
|
23
|
-
let camera;
|
|
24
|
-
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
mockGame = createMockGame();
|
|
27
|
-
camera = new Camera3D({ perspective: 800 });
|
|
28
|
-
|
|
29
|
-
// Reset Painter mocks
|
|
30
|
-
if (Painter.save) Painter.save.mockClear?.();
|
|
31
|
-
if (Painter.restore) Painter.restore.mockClear?.();
|
|
32
|
-
if (Painter.translateTo) Painter.translateTo = vi.fn();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe("constructor", () => {
|
|
36
|
-
it("should throw if camera is not provided", () => {
|
|
37
|
-
expect(() => {
|
|
38
|
-
new Scene3D(mockGame, {});
|
|
39
|
-
}).toThrow("Scene3D requires a camera option");
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("should initialize with camera", () => {
|
|
43
|
-
const scene = new Scene3D(mockGame, { camera });
|
|
44
|
-
|
|
45
|
-
expect(scene.camera).toBe(camera);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("should default depthSort to true", () => {
|
|
49
|
-
const scene = new Scene3D(mockGame, { camera });
|
|
50
|
-
|
|
51
|
-
expect(scene.depthSort).toBe(true);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it("should default scaleByDepth to true", () => {
|
|
55
|
-
const scene = new Scene3D(mockGame, { camera });
|
|
56
|
-
|
|
57
|
-
expect(scene.scaleByDepth).toBe(true);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it("should accept custom options", () => {
|
|
61
|
-
const scene = new Scene3D(mockGame, {
|
|
62
|
-
camera,
|
|
63
|
-
depthSort: false,
|
|
64
|
-
scaleByDepth: false,
|
|
65
|
-
x: 100,
|
|
66
|
-
y: 200,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
expect(scene.depthSort).toBe(false);
|
|
70
|
-
expect(scene.scaleByDepth).toBe(false);
|
|
71
|
-
expect(scene.x).toBe(100);
|
|
72
|
-
expect(scene.y).toBe(200);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
describe("draw with depth sorting", () => {
|
|
77
|
-
it("should sort children back-to-front when depthSort is true", () => {
|
|
78
|
-
const scene = new Scene3D(mockGame, {
|
|
79
|
-
camera,
|
|
80
|
-
depthSort: true,
|
|
81
|
-
scaleByDepth: false,
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// Setup Painter mock
|
|
85
|
-
Painter.save = vi.fn();
|
|
86
|
-
Painter.restore = vi.fn();
|
|
87
|
-
Painter.translateTo = vi.fn();
|
|
88
|
-
Painter.ctx = { scale: vi.fn() };
|
|
89
|
-
|
|
90
|
-
// Add children at different z depths
|
|
91
|
-
const front = createMockChild({ x: 0, y: 0, z: -100 });
|
|
92
|
-
const middle = createMockChild({ x: 0, y: 0, z: 0 });
|
|
93
|
-
const back = createMockChild({ x: 0, y: 0, z: 100 });
|
|
94
|
-
|
|
95
|
-
scene._collection = {
|
|
96
|
-
children: [front, middle, back],
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
// Call draw
|
|
100
|
-
scene.draw();
|
|
101
|
-
|
|
102
|
-
// Children should be rendered back-to-front
|
|
103
|
-
// So 'back' should be called before 'front'
|
|
104
|
-
const callOrder = [];
|
|
105
|
-
if (back.draw.mock.calls.length) callOrder.push("back");
|
|
106
|
-
if (middle.draw.mock.calls.length) callOrder.push("middle");
|
|
107
|
-
if (front.draw.mock.calls.length) callOrder.push("front");
|
|
108
|
-
|
|
109
|
-
// All should be called
|
|
110
|
-
expect(back.draw).toHaveBeenCalled();
|
|
111
|
-
expect(middle.draw).toHaveBeenCalled();
|
|
112
|
-
expect(front.draw).toHaveBeenCalled();
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it("should not sort when depthSort is false", () => {
|
|
116
|
-
const scene = new Scene3D(mockGame, {
|
|
117
|
-
camera,
|
|
118
|
-
depthSort: false,
|
|
119
|
-
scaleByDepth: false,
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
Painter.save = vi.fn();
|
|
123
|
-
Painter.restore = vi.fn();
|
|
124
|
-
Painter.translateTo = vi.fn();
|
|
125
|
-
Painter.ctx = { scale: vi.fn() };
|
|
126
|
-
|
|
127
|
-
const child1 = createMockChild({ z: 100 });
|
|
128
|
-
const child2 = createMockChild({ z: -100 });
|
|
129
|
-
|
|
130
|
-
scene._collection = {
|
|
131
|
-
children: [child1, child2],
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
scene.draw();
|
|
135
|
-
|
|
136
|
-
// Both should be drawn
|
|
137
|
-
expect(child1.draw).toHaveBeenCalled();
|
|
138
|
-
expect(child2.draw).toHaveBeenCalled();
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
describe("draw with perspective scaling", () => {
|
|
143
|
-
it("should scale children by perspective when scaleByDepth is true", () => {
|
|
144
|
-
const scene = new Scene3D(mockGame, {
|
|
145
|
-
camera,
|
|
146
|
-
depthSort: false,
|
|
147
|
-
scaleByDepth: true,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
Painter.save = vi.fn();
|
|
151
|
-
Painter.restore = vi.fn();
|
|
152
|
-
Painter.translateTo = vi.fn();
|
|
153
|
-
Painter.ctx = { scale: vi.fn() };
|
|
154
|
-
|
|
155
|
-
const child = createMockChild({ z: 0 });
|
|
156
|
-
scene._collection = {
|
|
157
|
-
children: [child],
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
scene.draw();
|
|
161
|
-
|
|
162
|
-
// Scale should be called
|
|
163
|
-
expect(Painter.ctx.scale).toHaveBeenCalled();
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it("should not scale when scaleByDepth is false", () => {
|
|
167
|
-
const scene = new Scene3D(mockGame, {
|
|
168
|
-
camera,
|
|
169
|
-
depthSort: false,
|
|
170
|
-
scaleByDepth: false,
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
Painter.save = vi.fn();
|
|
174
|
-
Painter.restore = vi.fn();
|
|
175
|
-
Painter.translateTo = vi.fn();
|
|
176
|
-
Painter.ctx = { scale: vi.fn() };
|
|
177
|
-
|
|
178
|
-
const child = createMockChild({ z: 0 });
|
|
179
|
-
scene._collection = {
|
|
180
|
-
children: [child],
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
scene.draw();
|
|
184
|
-
|
|
185
|
-
// Scale should not be called
|
|
186
|
-
expect(Painter.ctx.scale).not.toHaveBeenCalled();
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
describe("draw visibility and culling", () => {
|
|
191
|
-
it("should skip invisible children", () => {
|
|
192
|
-
const scene = new Scene3D(mockGame, {
|
|
193
|
-
camera,
|
|
194
|
-
depthSort: false,
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
Painter.save = vi.fn();
|
|
198
|
-
Painter.restore = vi.fn();
|
|
199
|
-
Painter.translateTo = vi.fn();
|
|
200
|
-
Painter.ctx = { scale: vi.fn() };
|
|
201
|
-
|
|
202
|
-
const visible = createMockChild({ visible: true });
|
|
203
|
-
const hidden = createMockChild({ visible: false });
|
|
204
|
-
|
|
205
|
-
scene._collection = {
|
|
206
|
-
children: [visible, hidden],
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
scene.draw();
|
|
210
|
-
|
|
211
|
-
expect(visible.draw).toHaveBeenCalled();
|
|
212
|
-
expect(hidden.draw).not.toHaveBeenCalled();
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it("should cull children behind camera", () => {
|
|
216
|
-
const scene = new Scene3D(mockGame, {
|
|
217
|
-
camera: new Camera3D({ perspective: 100 }),
|
|
218
|
-
depthSort: false,
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
Painter.save = vi.fn();
|
|
222
|
-
Painter.restore = vi.fn();
|
|
223
|
-
Painter.translateTo = vi.fn();
|
|
224
|
-
Painter.ctx = { scale: vi.fn() };
|
|
225
|
-
|
|
226
|
-
// Child far behind camera (z = -200, camera.perspective = 100)
|
|
227
|
-
// After projection: if z < -perspective + 10, cull it
|
|
228
|
-
const farBehind = createMockChild({ z: 200 }); // After projection z will be positive
|
|
229
|
-
const inFront = createMockChild({ z: -50 });
|
|
230
|
-
|
|
231
|
-
scene._collection = {
|
|
232
|
-
children: [farBehind, inFront],
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
scene.draw();
|
|
236
|
-
|
|
237
|
-
// Both should be drawn as they're not behind camera
|
|
238
|
-
expect(inFront.draw).toHaveBeenCalled();
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it("should default z to 0 for children without z property", () => {
|
|
242
|
-
const scene = new Scene3D(mockGame, {
|
|
243
|
-
camera,
|
|
244
|
-
depthSort: false,
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
Painter.save = vi.fn();
|
|
248
|
-
Painter.restore = vi.fn();
|
|
249
|
-
Painter.translateTo = vi.fn();
|
|
250
|
-
Painter.ctx = { scale: vi.fn() };
|
|
251
|
-
|
|
252
|
-
const noZ = createMockChild({ x: 100, y: 100 });
|
|
253
|
-
delete noZ.z; // No z property
|
|
254
|
-
|
|
255
|
-
scene._collection = {
|
|
256
|
-
children: [noZ],
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
// Should not throw
|
|
260
|
-
expect(() => scene.draw()).not.toThrow();
|
|
261
|
-
expect(noZ.draw).toHaveBeenCalled();
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
describe("draw transformations", () => {
|
|
266
|
-
it("should save and restore for each child", () => {
|
|
267
|
-
const scene = new Scene3D(mockGame, {
|
|
268
|
-
camera,
|
|
269
|
-
depthSort: false,
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
Painter.save = vi.fn();
|
|
273
|
-
Painter.restore = vi.fn();
|
|
274
|
-
Painter.translateTo = vi.fn();
|
|
275
|
-
Painter.ctx = { scale: vi.fn() };
|
|
276
|
-
|
|
277
|
-
const child1 = createMockChild();
|
|
278
|
-
const child2 = createMockChild();
|
|
279
|
-
|
|
280
|
-
scene._collection = {
|
|
281
|
-
children: [child1, child2],
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
scene.draw();
|
|
285
|
-
|
|
286
|
-
// Should call save/restore for each child
|
|
287
|
-
expect(Painter.save).toHaveBeenCalledTimes(2);
|
|
288
|
-
expect(Painter.restore).toHaveBeenCalledTimes(2);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
it("should translate to projected position", () => {
|
|
292
|
-
const scene = new Scene3D(mockGame, {
|
|
293
|
-
camera: new Camera3D(), // No rotation
|
|
294
|
-
depthSort: false,
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
Painter.save = vi.fn();
|
|
298
|
-
Painter.restore = vi.fn();
|
|
299
|
-
Painter.translateTo = vi.fn();
|
|
300
|
-
Painter.ctx = { scale: vi.fn() };
|
|
301
|
-
|
|
302
|
-
const child = createMockChild({ x: 100, y: 50, z: 0 });
|
|
303
|
-
scene._collection = {
|
|
304
|
-
children: [child],
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
scene.draw();
|
|
308
|
-
|
|
309
|
-
// With no rotation and z=0, projected position should match input
|
|
310
|
-
expect(Painter.translateTo).toHaveBeenCalledWith(100, 50);
|
|
311
|
-
});
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
describe("integration with Camera3D projection", () => {
|
|
315
|
-
it("should use camera projection for positioning", () => {
|
|
316
|
-
const mockCamera = {
|
|
317
|
-
project: vi.fn().mockReturnValue({
|
|
318
|
-
x: 150,
|
|
319
|
-
y: 75,
|
|
320
|
-
z: 50,
|
|
321
|
-
scale: 0.8,
|
|
322
|
-
}),
|
|
323
|
-
perspective: 800,
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const scene = new Scene3D(mockGame, {
|
|
327
|
-
camera: mockCamera,
|
|
328
|
-
depthSort: false,
|
|
329
|
-
scaleByDepth: true,
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
Painter.save = vi.fn();
|
|
333
|
-
Painter.restore = vi.fn();
|
|
334
|
-
Painter.translateTo = vi.fn();
|
|
335
|
-
Painter.ctx = { scale: vi.fn() };
|
|
336
|
-
|
|
337
|
-
const child = createMockChild({ x: 100, y: 50, z: 25 });
|
|
338
|
-
scene._collection = {
|
|
339
|
-
children: [child],
|
|
340
|
-
};
|
|
341
|
-
|
|
342
|
-
scene.draw();
|
|
343
|
-
|
|
344
|
-
// Should call camera.project with child coordinates
|
|
345
|
-
expect(mockCamera.project).toHaveBeenCalledWith(100, 50, 25);
|
|
346
|
-
|
|
347
|
-
// Should use projected values
|
|
348
|
-
expect(Painter.translateTo).toHaveBeenCalledWith(150, 75);
|
|
349
|
-
expect(Painter.ctx.scale).toHaveBeenCalledWith(0.8, 0.8);
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
});
|
package/vite.config.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from "vite";
|
|
2
|
-
import path from "path";
|
|
3
|
-
|
|
4
|
-
const libEntry = path.resolve(__dirname, "src/index.js");
|
|
5
|
-
|
|
6
|
-
export default defineConfig(({ mode }) => {
|
|
7
|
-
const isDebug = mode === "debug";
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
server: {
|
|
11
|
-
port: 9195,
|
|
12
|
-
strictPort: true, // Don't try other ports if 9195 is in use
|
|
13
|
-
},
|
|
14
|
-
build: {
|
|
15
|
-
lib: {
|
|
16
|
-
entry: libEntry,
|
|
17
|
-
name: "GCanvas",
|
|
18
|
-
formats: isDebug ? ["umd"] : ["umd", "es"],
|
|
19
|
-
fileName: (format) => {
|
|
20
|
-
if (isDebug) return "gcanvas.debug.js";
|
|
21
|
-
return `gcanvas.${format}.js`;
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
minify: isDebug ? false : "terser",
|
|
25
|
-
terserOptions: {
|
|
26
|
-
compress: true,
|
|
27
|
-
mangle: true,
|
|
28
|
-
format: {
|
|
29
|
-
comments: false,
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
outDir: "dist",
|
|
33
|
-
emptyOutDir: true,
|
|
34
|
-
rollupOptions: {
|
|
35
|
-
output: [
|
|
36
|
-
{
|
|
37
|
-
format: "umd",
|
|
38
|
-
entryFileNames: "gcanvas.umd.js",
|
|
39
|
-
name: "GCanvas",
|
|
40
|
-
globals: {},
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
format: "es",
|
|
44
|
-
entryFileNames: "gcanvas.es.js",
|
|
45
|
-
},
|
|
46
|
-
],
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
};
|
|
50
|
-
});
|
package/vitest.config.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config';
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
environment: 'jsdom',
|
|
6
|
-
globals: true,
|
|
7
|
-
setupFiles: ['./test/setup.js'],
|
|
8
|
-
coverage: {
|
|
9
|
-
provider: 'v8',
|
|
10
|
-
reporter: ['text', 'json', 'html'],
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
});
|