@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
package/demos/js/gendream.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fractal Plasma - Generative Art Demo
|
|
3
|
-
*
|
|
4
|
-
* Animated plasma effect using Fractals.applyColorScheme()
|
|
5
|
-
* for trippy color palettes. Fast single-image rendering.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import { Game, ImageGo, Painter } from '../../src/index.js';
|
|
9
|
-
import { Fractals } from '../../src/math/fractal.js';
|
|
10
|
-
|
|
11
|
-
class PlasmaDemo extends Game {
|
|
12
|
-
constructor(canvas) {
|
|
13
|
-
super(canvas);
|
|
14
|
-
this.backgroundColor = '#000';
|
|
15
|
-
this.enableFluidSize();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
init() {
|
|
19
|
-
super.init();
|
|
20
|
-
|
|
21
|
-
// Render at moderate res for balance of quality and performance
|
|
22
|
-
this.plasmaWidth = 512;
|
|
23
|
-
this.plasmaHeight = 512;
|
|
24
|
-
|
|
25
|
-
// Create plasma data buffer
|
|
26
|
-
this.plasmaData = new Uint8Array(this.plasmaWidth * this.plasmaHeight);
|
|
27
|
-
|
|
28
|
-
// Create ImageData for rendering
|
|
29
|
-
this.imageData = Painter.img.createImageData(this.plasmaWidth, this.plasmaHeight);
|
|
30
|
-
|
|
31
|
-
// Create ImageGo to display (fullscreen from top-left corner)
|
|
32
|
-
this.plasmaImage = new ImageGo(this, this.imageData, {
|
|
33
|
-
x: 0,
|
|
34
|
-
y: 0,
|
|
35
|
-
width: this.width,
|
|
36
|
-
height: this.height,
|
|
37
|
-
anchor: 'top-left',
|
|
38
|
-
});
|
|
39
|
-
this.pipeline.add(this.plasmaImage);
|
|
40
|
-
|
|
41
|
-
// Animation state
|
|
42
|
-
this.baseTime = 0; // Steady clock
|
|
43
|
-
this.time = 0; // Modulated time for fluid speed
|
|
44
|
-
this.colorSchemeIndex = 0;
|
|
45
|
-
// Only use schemes that animate well with hueShift
|
|
46
|
-
this.colorSchemes = ['electric', 'rainbow', 'historic', 'psychedelic', 'neon'];
|
|
47
|
-
this.currentScheme = this.colorSchemes[0];
|
|
48
|
-
this.schemeTime = 0;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// HSL to RGB helper (needed for some color schemes)
|
|
52
|
-
this.hslToRgb = (h, s, l) => {
|
|
53
|
-
h /= 360;
|
|
54
|
-
const a = s * Math.min(l, 1 - l);
|
|
55
|
-
const f = (n) => {
|
|
56
|
-
const k = (n + h * 12) % 12;
|
|
57
|
-
return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
58
|
-
};
|
|
59
|
-
return [Math.round(f(0) * 255), Math.round(f(8) * 255), Math.round(f(4) * 255)];
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
update(dt) {
|
|
64
|
-
super.update(dt);
|
|
65
|
-
|
|
66
|
-
this.baseTime += dt;
|
|
67
|
-
this.schemeTime += dt;
|
|
68
|
-
|
|
69
|
-
// Fluid speed modulation - breathing effect (slow -> fast -> slow)
|
|
70
|
-
// Speed varies from 0.3x to 1.7x in smooth waves
|
|
71
|
-
const speedMod = 1 + Math.sin(this.baseTime * 0.4) * 0.7;
|
|
72
|
-
this.time += dt * speedMod;
|
|
73
|
-
|
|
74
|
-
// Cycle color schemes every 5 seconds
|
|
75
|
-
if (this.schemeTime > 5) {
|
|
76
|
-
this.schemeTime = 0;
|
|
77
|
-
this.colorSchemeIndex = (this.colorSchemeIndex + 1) % this.colorSchemes.length;
|
|
78
|
-
this.currentScheme = this.colorSchemes[this.colorSchemeIndex];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Generate animated plasma
|
|
82
|
-
this.generatePlasma();
|
|
83
|
-
|
|
84
|
-
// Apply color scheme (use custom for trippy ones, library for others)
|
|
85
|
-
if (this.currentScheme === 'psychedelic' || this.currentScheme === 'neon') {
|
|
86
|
-
this.applyCustomScheme(this.currentScheme, this.time * 50);
|
|
87
|
-
} else {
|
|
88
|
-
Fractals.applyColorScheme(
|
|
89
|
-
this.plasmaData,
|
|
90
|
-
this.imageData,
|
|
91
|
-
this.currentScheme,
|
|
92
|
-
256, // iterations (for normalization)
|
|
93
|
-
this.time * 50, // hue shift for animation
|
|
94
|
-
this.hslToRgb
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Update the image
|
|
99
|
-
this.plasmaImage.shape.bitmap = this.imageData;
|
|
100
|
-
|
|
101
|
-
// Scale to fit screen (fullscreen from top-left)
|
|
102
|
-
this.plasmaImage.x = 0;
|
|
103
|
-
this.plasmaImage.y = 0;
|
|
104
|
-
this.plasmaImage.width = this.width;
|
|
105
|
-
this.plasmaImage.height = this.height;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
applyCustomScheme(scheme, hueShift) {
|
|
109
|
-
const data = this.imageData.data;
|
|
110
|
-
|
|
111
|
-
for (let i = 0; i < this.plasmaData.length; i++) {
|
|
112
|
-
const v = this.plasmaData[i];
|
|
113
|
-
const idx = i * 4;
|
|
114
|
-
|
|
115
|
-
if (scheme === 'psychedelic') {
|
|
116
|
-
// Multi-frequency color cycling for maximum trippy effect
|
|
117
|
-
const h1 = (v * 2 + hueShift) % 360;
|
|
118
|
-
const h2 = (v * 3 + hueShift * 1.5) % 360;
|
|
119
|
-
const h3 = (v * 5 + hueShift * 0.7) % 360;
|
|
120
|
-
|
|
121
|
-
// Blend multiple hues
|
|
122
|
-
const [r1, g1, b1] = this.hslToRgb(h1, 1, 0.5);
|
|
123
|
-
const [r2, g2, b2] = this.hslToRgb(h2, 0.8, 0.6);
|
|
124
|
-
const [r3, g3, b3] = this.hslToRgb(h3, 0.9, 0.4);
|
|
125
|
-
|
|
126
|
-
// Mix based on value bands
|
|
127
|
-
const blend = Math.sin(v * 0.05 + hueShift * 0.01) * 0.5 + 0.5;
|
|
128
|
-
data[idx] = Math.floor(r1 * blend + r2 * (1 - blend));
|
|
129
|
-
data[idx + 1] = Math.floor(g1 * (1 - blend) + g3 * blend);
|
|
130
|
-
data[idx + 2] = Math.floor(b2 * blend + b3 * (1 - blend));
|
|
131
|
-
} else if (scheme === 'neon') {
|
|
132
|
-
// Bright neon colors on dark background
|
|
133
|
-
const phase = (v + hueShift) % 256;
|
|
134
|
-
const intensity = Math.sin(v * 0.1) * 0.5 + 0.5;
|
|
135
|
-
|
|
136
|
-
// Neon pink, cyan, green cycling
|
|
137
|
-
if (phase < 85) {
|
|
138
|
-
const t = phase / 85;
|
|
139
|
-
data[idx] = Math.floor(255 * intensity); // Pink/Magenta
|
|
140
|
-
data[idx + 1] = Math.floor(50 * t * intensity);
|
|
141
|
-
data[idx + 2] = Math.floor(255 * (1 - t * 0.5) * intensity);
|
|
142
|
-
} else if (phase < 170) {
|
|
143
|
-
const t = (phase - 85) / 85;
|
|
144
|
-
data[idx] = Math.floor(50 * (1 - t) * intensity);
|
|
145
|
-
data[idx + 1] = Math.floor(255 * intensity); // Cyan
|
|
146
|
-
data[idx + 2] = Math.floor(255 * intensity);
|
|
147
|
-
} else {
|
|
148
|
-
const t = (phase - 170) / 86;
|
|
149
|
-
data[idx] = Math.floor(50 * t * intensity);
|
|
150
|
-
data[idx + 1] = Math.floor(255 * (1 - t * 0.5) * intensity); // Green
|
|
151
|
-
data[idx + 2] = Math.floor(50 * intensity);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
data[idx + 3] = 255;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
generatePlasma() {
|
|
159
|
-
const w = this.plasmaWidth;
|
|
160
|
-
const h = this.plasmaHeight;
|
|
161
|
-
const t = this.time;
|
|
162
|
-
|
|
163
|
-
// Multiple overlapping sine waves create plasma effect
|
|
164
|
-
for (let y = 0; y < h; y++) {
|
|
165
|
-
for (let x = 0; x < w; x++) {
|
|
166
|
-
// Normalized coordinates
|
|
167
|
-
const nx = x / w;
|
|
168
|
-
const ny = y / h;
|
|
169
|
-
|
|
170
|
-
// Classic plasma formula with multiple sine waves
|
|
171
|
-
let value = 0;
|
|
172
|
-
|
|
173
|
-
// Wave 1: horizontal
|
|
174
|
-
value += Math.sin(nx * 10 + t * 2);
|
|
175
|
-
|
|
176
|
-
// Wave 2: vertical
|
|
177
|
-
value += Math.sin(ny * 10 + t * 1.5);
|
|
178
|
-
|
|
179
|
-
// Wave 3: diagonal
|
|
180
|
-
value += Math.sin((nx + ny) * 10 + t);
|
|
181
|
-
|
|
182
|
-
// Wave 4: radial from center
|
|
183
|
-
const cx = nx - 0.5;
|
|
184
|
-
const cy = ny - 0.5;
|
|
185
|
-
const dist = Math.sqrt(cx * cx + cy * cy);
|
|
186
|
-
value += Math.sin(dist * 20 - t * 3);
|
|
187
|
-
|
|
188
|
-
// Wave 5: spiral
|
|
189
|
-
const angle = Math.atan2(cy, cx);
|
|
190
|
-
value += Math.sin(angle * 5 + dist * 15 - t * 2);
|
|
191
|
-
|
|
192
|
-
// Wave 6: interference pattern
|
|
193
|
-
value += Math.sin(nx * 15 * Math.sin(t * 0.5) + ny * 15 * Math.cos(t * 0.5));
|
|
194
|
-
|
|
195
|
-
// Normalize to 0-255 range
|
|
196
|
-
// value is roughly -6 to +6, normalize to 0-255
|
|
197
|
-
const normalized = Math.floor(((value + 6) / 12) * 255);
|
|
198
|
-
|
|
199
|
-
this.plasmaData[y * w + x] = Math.max(0, Math.min(255, normalized));
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
window.addEventListener('load', () => {
|
|
206
|
-
const canvas = document.getElementById('game');
|
|
207
|
-
const demo = new PlasmaDemo(canvas);
|
|
208
|
-
demo.start();
|
|
209
|
-
});
|
package/demos/js/group.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Game,
|
|
3
|
-
GameObject,
|
|
4
|
-
Group,
|
|
5
|
-
Rectangle,
|
|
6
|
-
Circle,
|
|
7
|
-
TextShape,
|
|
8
|
-
FPSCounter,
|
|
9
|
-
} from "../../src/index";
|
|
10
|
-
|
|
11
|
-
export class MyGame extends Game {
|
|
12
|
-
constructor(canvas) {
|
|
13
|
-
super(canvas);
|
|
14
|
-
this.enableFluidSize();
|
|
15
|
-
this.backgroundColor = "black";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
update(dt) {
|
|
19
|
-
super.update(dt);
|
|
20
|
-
// Use transform API for positioning
|
|
21
|
-
this.groupDemo.transform.position(this.width / 2, this.height / 2);
|
|
22
|
-
this.pipeline.update(dt);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
init() {
|
|
26
|
-
super.init();
|
|
27
|
-
this.groupDemo = new GroupDemo(this);
|
|
28
|
-
this.pipeline.add(this.groupDemo);
|
|
29
|
-
this.pipeline.add(
|
|
30
|
-
new FPSCounter(this, {
|
|
31
|
-
anchor: "bottom-right",
|
|
32
|
-
})
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* GroupDemo
|
|
39
|
-
*
|
|
40
|
-
* Demonstrates the Transform API with groups:
|
|
41
|
-
* - Group-wide rotation & scaling using transform.rotation() and transform.scale()
|
|
42
|
-
* - Child positioning using transform.position()
|
|
43
|
-
* - Batch operations using forEachTransform()
|
|
44
|
-
* - Circles arranged radially, color-shifting via HSL
|
|
45
|
-
*/
|
|
46
|
-
export class GroupDemo extends GameObject {
|
|
47
|
-
constructor(game) {
|
|
48
|
-
super(game);
|
|
49
|
-
// Create a Group and set dimensions using Transform API
|
|
50
|
-
this.group = new Group({ debug: true });
|
|
51
|
-
this.group.transform.size(450, 450);
|
|
52
|
-
|
|
53
|
-
// 1) A central rectangle
|
|
54
|
-
const centerRect = new Rectangle({
|
|
55
|
-
width: 145,
|
|
56
|
-
height: 60,
|
|
57
|
-
color: "#222",
|
|
58
|
-
debug: true,
|
|
59
|
-
});
|
|
60
|
-
this.group.add(centerRect);
|
|
61
|
-
|
|
62
|
-
// 2) Some text in the middle
|
|
63
|
-
const centerText = new TextShape("Transform API Demo!", {
|
|
64
|
-
font: "18px sans-serif",
|
|
65
|
-
color: "#FFF",
|
|
66
|
-
align: "center",
|
|
67
|
-
baseline: "middle",
|
|
68
|
-
opacity: 0.5,
|
|
69
|
-
});
|
|
70
|
-
this.group.add(centerText);
|
|
71
|
-
|
|
72
|
-
// 3) Create a radial pattern of circles around the origin
|
|
73
|
-
this.circles = [];
|
|
74
|
-
this.circleCount = 20;
|
|
75
|
-
const circleRadius = 200;
|
|
76
|
-
|
|
77
|
-
for (let i = 0; i < this.circleCount; i++) {
|
|
78
|
-
const angle = (Math.PI * 2 * i) / this.circleCount;
|
|
79
|
-
const x = Math.cos(angle) * circleRadius;
|
|
80
|
-
const y = Math.sin(angle) * circleRadius;
|
|
81
|
-
|
|
82
|
-
const circle = new Circle(20, {
|
|
83
|
-
color: "#ff0",
|
|
84
|
-
stroke: "#FFF",
|
|
85
|
-
lineWidth: 2,
|
|
86
|
-
visible: true,
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Use Transform API to position the circle
|
|
90
|
-
circle.transform.position(x, y);
|
|
91
|
-
|
|
92
|
-
this.circles.push(circle);
|
|
93
|
-
this.group.add(circle);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Initialize group transforms using the Transform API
|
|
97
|
-
this.group.transform
|
|
98
|
-
.rotation(0)
|
|
99
|
-
.scale(1);
|
|
100
|
-
|
|
101
|
-
this.elapsed = 0;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* update(dt) - Animate using the Transform API:
|
|
106
|
-
* 1) Group rotation & scale using transform.rotation() and transform.scale()
|
|
107
|
-
* 2) Each circle's color via forEachTransform pattern
|
|
108
|
-
* 3) Circle visibility cycling
|
|
109
|
-
* @param {number} dt - Delta time in seconds.
|
|
110
|
-
*/
|
|
111
|
-
update(dt) {
|
|
112
|
-
super.update(dt);
|
|
113
|
-
this.elapsed += dt;
|
|
114
|
-
|
|
115
|
-
// 1) Animate group using Transform API (fluent chaining)
|
|
116
|
-
const pulse = 0.5 * Math.sin(this.elapsed * 2);
|
|
117
|
-
this.group.transform
|
|
118
|
-
.rotation(this.elapsed * 24)
|
|
119
|
-
.scale(1 + pulse);
|
|
120
|
-
|
|
121
|
-
// 2) Animate each circle's color & visibility
|
|
122
|
-
const cycleSpeed = 0.1;
|
|
123
|
-
const flashIndex = Math.floor(this.elapsed / cycleSpeed) % this.circleCount;
|
|
124
|
-
|
|
125
|
-
this.circles.forEach((circle, i) => {
|
|
126
|
-
// Animate color
|
|
127
|
-
const hue = (this.elapsed * 50 + i * 40) % 360;
|
|
128
|
-
circle.color = `hsl(${hue}, 90%, 60%)`;
|
|
129
|
-
// One circle is invisible; all others remain visible
|
|
130
|
-
circle.visible = i !== flashIndex;
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
this.group.update(dt);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
draw() {
|
|
137
|
-
this.logger.log("GroupDemo: render");
|
|
138
|
-
this.group.render();
|
|
139
|
-
}
|
|
140
|
-
}
|
package/demos/js/info-toggle.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-injects a toggle button for #info overlay on mobile devices.
|
|
3
|
-
* Include this script in demo pages that have an #info element.
|
|
4
|
-
*/
|
|
5
|
-
(function() {
|
|
6
|
-
document.addEventListener("DOMContentLoaded", function() {
|
|
7
|
-
const info = document.getElementById("info");
|
|
8
|
-
if (!info) return;
|
|
9
|
-
|
|
10
|
-
// Create toggle button
|
|
11
|
-
const toggle = document.createElement("button");
|
|
12
|
-
toggle.id = "info-toggle";
|
|
13
|
-
toggle.textContent = "?";
|
|
14
|
-
toggle.setAttribute("aria-label", "Toggle info panel");
|
|
15
|
-
|
|
16
|
-
// Insert button before info element
|
|
17
|
-
info.parentNode.insertBefore(toggle, info);
|
|
18
|
-
|
|
19
|
-
// Toggle functionality
|
|
20
|
-
toggle.addEventListener("click", function() {
|
|
21
|
-
info.classList.toggle("open");
|
|
22
|
-
toggle.textContent = info.classList.contains("open") ? "×" : "?";
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
})();
|