@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,64 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
-
import { Rectangle } from "../../src/shapes";
|
|
3
|
-
import { Painter } from "../../src/painter/painter";
|
|
4
|
-
|
|
5
|
-
describe("Rectangle", () => {
|
|
6
|
-
it("should initialize with default values", () => {
|
|
7
|
-
const rectangle = new Rectangle();
|
|
8
|
-
expect(rectangle.x).toBe(0);
|
|
9
|
-
expect(rectangle.y).toBe(0);
|
|
10
|
-
expect(rectangle.width).toBe(0);
|
|
11
|
-
expect(rectangle.height).toBe(0);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it("should initialize with custom values", () => {
|
|
15
|
-
const rectangle = new Rectangle({ x: 10, y: 20, width: 100, height: 200 });
|
|
16
|
-
expect(rectangle.x).toBe(10);
|
|
17
|
-
expect(rectangle.y).toBe(20);
|
|
18
|
-
expect(rectangle.width).toBe(100);
|
|
19
|
-
expect(rectangle.height).toBe(200);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("should draw a filled rectangle correctly using Painter.", () => {
|
|
23
|
-
Painter.shapes = {
|
|
24
|
-
rect: vi.fn(),
|
|
25
|
-
};
|
|
26
|
-
const rectangle = new Rectangle({
|
|
27
|
-
x: 10,
|
|
28
|
-
y: 20,
|
|
29
|
-
width: 100,
|
|
30
|
-
height: 200,
|
|
31
|
-
color: "red",
|
|
32
|
-
});
|
|
33
|
-
rectangle.drawRect();
|
|
34
|
-
// painter should translate to the rectangle's center
|
|
35
|
-
expect(Painter.shapes.rect).toHaveBeenCalledWith(-50, -100, 100, 200, "red");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("should draw an outlined rectangle correctly using Painter.", () => {
|
|
39
|
-
Painter.shapes = {
|
|
40
|
-
outlineRect: vi.fn(),
|
|
41
|
-
rect: vi.fn(),
|
|
42
|
-
};
|
|
43
|
-
const rectangle = new Rectangle({
|
|
44
|
-
x: 10,
|
|
45
|
-
y: 20,
|
|
46
|
-
width: 100,
|
|
47
|
-
height: 200,
|
|
48
|
-
color: "red",
|
|
49
|
-
stroke: "blue",
|
|
50
|
-
lineWidth: 2,
|
|
51
|
-
});
|
|
52
|
-
rectangle.drawRect();
|
|
53
|
-
// painter should translate to the rectangle's center
|
|
54
|
-
expect(Painter.shapes.outlineRect).toHaveBeenCalledWith(
|
|
55
|
-
-50,
|
|
56
|
-
-100,
|
|
57
|
-
100,
|
|
58
|
-
200,
|
|
59
|
-
"blue",
|
|
60
|
-
2
|
|
61
|
-
);
|
|
62
|
-
expect(Painter.shapes.rect).toHaveBeenCalledWith(-50, -100, 100, 200, "red");
|
|
63
|
-
});
|
|
64
|
-
});
|
|
@@ -1,379 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
-
import { Transform } from '../../src/shapes/transform.js';
|
|
3
|
-
import { Rectangle } from '../../src/shapes/rect.js';
|
|
4
|
-
import { Group } from '../../src/shapes/group.js';
|
|
5
|
-
|
|
6
|
-
describe('Transform', () => {
|
|
7
|
-
let rect;
|
|
8
|
-
let transform;
|
|
9
|
-
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
rect = new Rectangle({ x: 0, y: 0, width: 100, height: 50 });
|
|
12
|
-
transform = rect.transform;
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe('initialization', () => {
|
|
16
|
-
it('should be created with owner reference', () => {
|
|
17
|
-
expect(transform).toBeInstanceOf(Transform);
|
|
18
|
-
expect(transform.owner).toBe(rect);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should have strictMode disabled by default', () => {
|
|
22
|
-
expect(Transform.strictMode).toBe(false);
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
describe('position methods', () => {
|
|
27
|
-
it('should set x position', () => {
|
|
28
|
-
const result = transform.x(100);
|
|
29
|
-
expect(rect.x).toBe(100);
|
|
30
|
-
expect(result).toBe(transform); // chainable
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('should set y position', () => {
|
|
34
|
-
const result = transform.y(200);
|
|
35
|
-
expect(rect.y).toBe(200);
|
|
36
|
-
expect(result).toBe(transform); // chainable
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should set position with position()', () => {
|
|
40
|
-
const result = transform.position(50, 75);
|
|
41
|
-
expect(rect.x).toBe(50);
|
|
42
|
-
expect(rect.y).toBe(75);
|
|
43
|
-
expect(result).toBe(transform);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('should translate by offset with translateBy()', () => {
|
|
47
|
-
transform.position(100, 100);
|
|
48
|
-
const result = transform.translateBy(25, -10);
|
|
49
|
-
expect(rect.x).toBe(125);
|
|
50
|
-
expect(rect.y).toBe(90);
|
|
51
|
-
expect(result).toBe(transform);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
describe('dimension methods', () => {
|
|
56
|
-
it('should set width', () => {
|
|
57
|
-
const result = transform.width(200);
|
|
58
|
-
expect(rect.width).toBe(200);
|
|
59
|
-
expect(result).toBe(transform);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('should set height', () => {
|
|
63
|
-
const result = transform.height(150);
|
|
64
|
-
expect(rect.height).toBe(150);
|
|
65
|
-
expect(result).toBe(transform);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should clamp negative width to 0', () => {
|
|
69
|
-
transform.width(-50);
|
|
70
|
-
expect(rect.width).toBe(0);
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('should clamp negative height to 0', () => {
|
|
74
|
-
transform.height(-50);
|
|
75
|
-
expect(rect.height).toBe(0);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it('should set size with size()', () => {
|
|
79
|
-
const result = transform.size(300, 200);
|
|
80
|
-
expect(rect.width).toBe(300);
|
|
81
|
-
expect(rect.height).toBe(200);
|
|
82
|
-
expect(result).toBe(transform);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
describe('rotation methods', () => {
|
|
87
|
-
it('should set rotation in degrees', () => {
|
|
88
|
-
const result = transform.rotation(45);
|
|
89
|
-
expect(rect._rotation).toBeCloseTo(Math.PI / 4);
|
|
90
|
-
expect(result).toBe(transform);
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('should set rotation in radians', () => {
|
|
94
|
-
const result = transform.rotationRad(Math.PI);
|
|
95
|
-
expect(rect._rotation).toBeCloseTo(Math.PI);
|
|
96
|
-
expect(result).toBe(transform);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should rotate by offset with rotateBy()', () => {
|
|
100
|
-
transform.rotation(45);
|
|
101
|
-
const result = transform.rotateBy(45);
|
|
102
|
-
expect(rect._rotation).toBeCloseTo(Math.PI / 2);
|
|
103
|
-
expect(result).toBe(transform);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
describe('scale methods', () => {
|
|
108
|
-
it('should set scaleX', () => {
|
|
109
|
-
const result = transform.scaleX(2);
|
|
110
|
-
expect(rect.scaleX).toBe(2);
|
|
111
|
-
expect(result).toBe(transform);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should set scaleY', () => {
|
|
115
|
-
const result = transform.scaleY(0.5);
|
|
116
|
-
expect(rect.scaleY).toBe(0.5);
|
|
117
|
-
expect(result).toBe(transform);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('should set uniform scale with scale()', () => {
|
|
121
|
-
const result = transform.scale(1.5);
|
|
122
|
-
expect(rect.scaleX).toBe(1.5);
|
|
123
|
-
expect(rect.scaleY).toBe(1.5);
|
|
124
|
-
expect(result).toBe(transform);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
it('should multiply scale with scaleBy()', () => {
|
|
128
|
-
transform.scale(2);
|
|
129
|
-
const result = transform.scaleBy(0.5);
|
|
130
|
-
expect(rect.scaleX).toBe(1);
|
|
131
|
-
expect(rect.scaleY).toBe(1);
|
|
132
|
-
expect(result).toBe(transform);
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
describe('batch operations', () => {
|
|
137
|
-
it('should set multiple properties with set()', () => {
|
|
138
|
-
const result = transform.set({
|
|
139
|
-
x: 100,
|
|
140
|
-
y: 200,
|
|
141
|
-
width: 150,
|
|
142
|
-
height: 75,
|
|
143
|
-
rotation: 90,
|
|
144
|
-
scaleX: 2,
|
|
145
|
-
scaleY: 0.5
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
expect(rect.x).toBe(100);
|
|
149
|
-
expect(rect.y).toBe(200);
|
|
150
|
-
expect(rect.width).toBe(150);
|
|
151
|
-
expect(rect.height).toBe(75);
|
|
152
|
-
expect(rect._rotation).toBeCloseTo(Math.PI / 2);
|
|
153
|
-
expect(rect.scaleX).toBe(2);
|
|
154
|
-
expect(rect.scaleY).toBe(0.5);
|
|
155
|
-
expect(result).toBe(transform);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should only set provided properties in set()', () => {
|
|
159
|
-
transform.position(10, 20);
|
|
160
|
-
transform.set({ x: 100 }); // only set x
|
|
161
|
-
expect(rect.x).toBe(100);
|
|
162
|
-
expect(rect.y).toBe(20); // unchanged
|
|
163
|
-
});
|
|
164
|
-
|
|
165
|
-
it('should reset transforms with reset()', () => {
|
|
166
|
-
transform.set({
|
|
167
|
-
rotation: 45,
|
|
168
|
-
scaleX: 2,
|
|
169
|
-
scaleY: 2
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
const result = transform.reset();
|
|
173
|
-
expect(rect._rotation).toBe(0);
|
|
174
|
-
expect(rect.scaleX).toBe(1);
|
|
175
|
-
expect(rect.scaleY).toBe(1);
|
|
176
|
-
expect(result).toBe(transform);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('should reset all with resetAll()', () => {
|
|
180
|
-
transform.set({
|
|
181
|
-
x: 100,
|
|
182
|
-
y: 200,
|
|
183
|
-
width: 300,
|
|
184
|
-
height: 400,
|
|
185
|
-
rotation: 45,
|
|
186
|
-
scaleX: 2,
|
|
187
|
-
scaleY: 2
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
const result = transform.resetAll();
|
|
191
|
-
expect(rect.x).toBe(0);
|
|
192
|
-
expect(rect.y).toBe(0);
|
|
193
|
-
expect(rect.width).toBe(0);
|
|
194
|
-
expect(rect.height).toBe(0);
|
|
195
|
-
expect(rect._rotation).toBe(0);
|
|
196
|
-
expect(rect.scaleX).toBe(1);
|
|
197
|
-
expect(rect.scaleY).toBe(1);
|
|
198
|
-
expect(result).toBe(transform);
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
describe('utility methods', () => {
|
|
203
|
-
it('should export to object with toObject()', () => {
|
|
204
|
-
transform.set({
|
|
205
|
-
x: 100,
|
|
206
|
-
y: 200,
|
|
207
|
-
width: 150,
|
|
208
|
-
height: 75,
|
|
209
|
-
rotation: 90,
|
|
210
|
-
scaleX: 2,
|
|
211
|
-
scaleY: 0.5
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
const obj = transform.toObject();
|
|
215
|
-
expect(obj.x).toBe(100);
|
|
216
|
-
expect(obj.y).toBe(200);
|
|
217
|
-
expect(obj.width).toBe(150);
|
|
218
|
-
expect(obj.height).toBe(75);
|
|
219
|
-
expect(obj.rotation).toBeCloseTo(90); // converted back to degrees
|
|
220
|
-
expect(obj.scaleX).toBe(2);
|
|
221
|
-
expect(obj.scaleY).toBe(0.5);
|
|
222
|
-
});
|
|
223
|
-
|
|
224
|
-
it('should copy from another transform with copyFrom()', () => {
|
|
225
|
-
const rect2 = new Rectangle({ x: 50, y: 60, width: 200, height: 100 });
|
|
226
|
-
rect2.transform.set({
|
|
227
|
-
rotation: 30,
|
|
228
|
-
scaleX: 1.5,
|
|
229
|
-
scaleY: 1.5
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
const result = transform.copyFrom(rect2.transform);
|
|
233
|
-
expect(rect.x).toBe(50);
|
|
234
|
-
expect(rect.y).toBe(60);
|
|
235
|
-
expect(rect._rotation).toBeCloseTo(Math.PI / 6);
|
|
236
|
-
expect(result).toBe(transform);
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it('should copy from plain object with copyFrom()', () => {
|
|
240
|
-
const result = transform.copyFrom({
|
|
241
|
-
x: 300,
|
|
242
|
-
y: 400,
|
|
243
|
-
rotation: 180
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
expect(rect.x).toBe(300);
|
|
247
|
-
expect(rect.y).toBe(400);
|
|
248
|
-
expect(rect._rotation).toBeCloseTo(Math.PI);
|
|
249
|
-
expect(result).toBe(transform);
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
describe('chaining', () => {
|
|
254
|
-
it('should support full chaining', () => {
|
|
255
|
-
transform
|
|
256
|
-
.position(100, 200)
|
|
257
|
-
.size(300, 150)
|
|
258
|
-
.rotation(45)
|
|
259
|
-
.scale(1.5)
|
|
260
|
-
.translateBy(10, 20)
|
|
261
|
-
.rotateBy(15);
|
|
262
|
-
|
|
263
|
-
expect(rect.x).toBe(110);
|
|
264
|
-
expect(rect.y).toBe(220);
|
|
265
|
-
expect(rect.width).toBe(300);
|
|
266
|
-
expect(rect.height).toBe(150);
|
|
267
|
-
expect(rect._rotation).toBeCloseTo((45 + 15) * Math.PI / 180);
|
|
268
|
-
expect(rect.scaleX).toBe(1.5);
|
|
269
|
-
expect(rect.scaleY).toBe(1.5);
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
describe('bounds dirty marking', () => {
|
|
274
|
-
it('should mark bounds dirty when position changes', () => {
|
|
275
|
-
rect._boundsDirty = false;
|
|
276
|
-
transform.x(100);
|
|
277
|
-
expect(rect.boundsDirty).toBe(true);
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
it('should mark bounds dirty when dimensions change', () => {
|
|
281
|
-
rect._boundsDirty = false;
|
|
282
|
-
transform.width(200);
|
|
283
|
-
expect(rect.boundsDirty).toBe(true);
|
|
284
|
-
});
|
|
285
|
-
|
|
286
|
-
it('should mark bounds dirty when rotation changes', () => {
|
|
287
|
-
rect._boundsDirty = false;
|
|
288
|
-
transform.rotation(45);
|
|
289
|
-
expect(rect.boundsDirty).toBe(true);
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('should mark bounds dirty when scale changes', () => {
|
|
293
|
-
rect._boundsDirty = false;
|
|
294
|
-
transform.scale(2);
|
|
295
|
-
expect(rect.boundsDirty).toBe(true);
|
|
296
|
-
});
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
describe('Group transform methods', () => {
|
|
301
|
-
let group;
|
|
302
|
-
|
|
303
|
-
beforeEach(() => {
|
|
304
|
-
group = new Group();
|
|
305
|
-
for (let i = 0; i < 3; i++) {
|
|
306
|
-
const rect = new Rectangle({ x: i * 50, y: 0, width: 30, height: 30 });
|
|
307
|
-
group.add(rect);
|
|
308
|
-
}
|
|
309
|
-
});
|
|
310
|
-
|
|
311
|
-
it('should apply forEachTransform to all children', () => {
|
|
312
|
-
group.forEachTransform((t) => t.rotation(45));
|
|
313
|
-
|
|
314
|
-
group.children.forEach((child) => {
|
|
315
|
-
expect(child._rotation).toBeCloseTo(Math.PI / 4);
|
|
316
|
-
});
|
|
317
|
-
});
|
|
318
|
-
|
|
319
|
-
it('should provide index to forEachTransform callback', () => {
|
|
320
|
-
group.forEachTransform((t, child, i) => t.rotation(i * 30));
|
|
321
|
-
|
|
322
|
-
expect(group.children[0]._rotation).toBeCloseTo(0);
|
|
323
|
-
expect(group.children[1]._rotation).toBeCloseTo(Math.PI / 6);
|
|
324
|
-
expect(group.children[2]._rotation).toBeCloseTo(Math.PI / 3);
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
it('should translate all children with translateChildren', () => {
|
|
328
|
-
group.translateChildren(10, 20);
|
|
329
|
-
|
|
330
|
-
expect(group.children[0].x).toBe(10);
|
|
331
|
-
expect(group.children[0].y).toBe(20);
|
|
332
|
-
expect(group.children[1].x).toBe(60);
|
|
333
|
-
expect(group.children[1].y).toBe(20);
|
|
334
|
-
expect(group.children[2].x).toBe(110);
|
|
335
|
-
expect(group.children[2].y).toBe(20);
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
it('should scale all children with scaleChildren', () => {
|
|
339
|
-
group.children.forEach((c) => c.transform.scale(2));
|
|
340
|
-
group.scaleChildren(0.5);
|
|
341
|
-
|
|
342
|
-
group.children.forEach((child) => {
|
|
343
|
-
expect(child.scaleX).toBe(1);
|
|
344
|
-
expect(child.scaleY).toBe(1);
|
|
345
|
-
});
|
|
346
|
-
});
|
|
347
|
-
|
|
348
|
-
it('should rotate all children with rotateChildren', () => {
|
|
349
|
-
group.children.forEach((c) => c.transform.rotation(0));
|
|
350
|
-
group.rotateChildren(90);
|
|
351
|
-
|
|
352
|
-
group.children.forEach((child) => {
|
|
353
|
-
expect(child._rotation).toBeCloseTo(Math.PI / 2);
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
it('should reset all children transforms with resetChildTransforms', () => {
|
|
358
|
-
group.children.forEach((c) => {
|
|
359
|
-
c.transform.rotation(45).scale(2);
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
group.resetChildTransforms();
|
|
363
|
-
|
|
364
|
-
group.children.forEach((child) => {
|
|
365
|
-
expect(child._rotation).toBe(0);
|
|
366
|
-
expect(child.scaleX).toBe(1);
|
|
367
|
-
expect(child.scaleY).toBe(1);
|
|
368
|
-
});
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
it('should be chainable', () => {
|
|
372
|
-
const result = group
|
|
373
|
-
.translateChildren(10, 10)
|
|
374
|
-
.scaleChildren(1.5)
|
|
375
|
-
.rotateChildren(15);
|
|
376
|
-
|
|
377
|
-
expect(result).toBe(group);
|
|
378
|
-
});
|
|
379
|
-
});
|