@guinetik/gcanvas 1.0.4 → 1.0.5
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/CNAME +1 -0
- package/dist/animations.html +31 -0
- package/dist/basic.html +38 -0
- package/dist/baskara.html +31 -0
- package/dist/bezier.html +35 -0
- package/dist/beziersignature.html +29 -0
- package/dist/blackhole.html +28 -0
- package/dist/blob.html +35 -0
- package/dist/coordinates.html +698 -0
- package/dist/cube3d.html +23 -0
- package/dist/demos.css +303 -0
- package/dist/dino.html +42 -0
- package/dist/easing.html +28 -0
- package/dist/events.html +195 -0
- package/dist/fluent.html +647 -0
- package/dist/fluid-simple.html +22 -0
- package/dist/fluid.html +37 -0
- package/dist/fractals.html +36 -0
- package/dist/gameobjects.html +626 -0
- package/dist/gcanvas.es.js +517 -0
- package/dist/gcanvas.es.min.js +1 -1
- package/dist/gcanvas.umd.js +1 -1
- package/dist/gcanvas.umd.min.js +1 -1
- package/dist/genart.html +26 -0
- package/dist/gendream.html +26 -0
- package/dist/group.html +36 -0
- package/dist/home.html +587 -0
- package/dist/hyperbolic001.html +23 -0
- package/dist/hyperbolic002.html +23 -0
- package/dist/hyperbolic003.html +23 -0
- package/dist/hyperbolic004.html +23 -0
- package/dist/hyperbolic005.html +22 -0
- package/dist/index.html +398 -0
- package/dist/isometric.html +34 -0
- package/dist/js/animations.js +452 -0
- package/dist/js/basic.js +204 -0
- package/dist/js/baskara.js +751 -0
- package/dist/js/bezier.js +692 -0
- package/dist/js/beziersignature.js +241 -0
- package/dist/js/blackhole/accretiondisk.obj.js +379 -0
- package/dist/js/blackhole/blackhole.obj.js +318 -0
- package/dist/js/blackhole/index.js +409 -0
- package/dist/js/blackhole/particle.js +56 -0
- package/dist/js/blackhole/starfield.obj.js +218 -0
- package/dist/js/blob.js +2276 -0
- package/dist/js/coordinates.js +840 -0
- package/dist/js/cube3d.js +789 -0
- package/dist/js/dino.js +1420 -0
- package/dist/js/easing.js +477 -0
- package/dist/js/fluent.js +183 -0
- package/dist/js/fluid-simple.js +253 -0
- package/dist/js/fluid.js +527 -0
- package/dist/js/fractals.js +932 -0
- package/dist/js/fractalworker.js +93 -0
- package/dist/js/gameobjects.js +176 -0
- package/dist/js/genart.js +268 -0
- package/dist/js/gendream.js +209 -0
- package/dist/js/group.js +140 -0
- package/dist/js/hyperbolic001.js +310 -0
- package/dist/js/hyperbolic002.js +388 -0
- package/dist/js/hyperbolic003.js +319 -0
- package/dist/js/hyperbolic004.js +345 -0
- package/dist/js/hyperbolic005.js +340 -0
- package/dist/js/info-toggle.js +25 -0
- package/dist/js/isometric.js +863 -0
- package/dist/js/kerr.js +1547 -0
- package/dist/js/lavalamp.js +590 -0
- package/dist/js/layout.js +354 -0
- package/dist/js/mondrian.js +285 -0
- package/dist/js/opacity.js +275 -0
- package/dist/js/painter.js +484 -0
- package/dist/js/particles-showcase.js +514 -0
- package/dist/js/particles.js +299 -0
- package/dist/js/patterns.js +397 -0
- package/dist/js/penrose/artifact.js +69 -0
- package/dist/js/penrose/blackhole.js +121 -0
- package/dist/js/penrose/constants.js +73 -0
- package/dist/js/penrose/game.js +943 -0
- package/dist/js/penrose/lore.js +278 -0
- package/dist/js/penrose/penrosescene.js +892 -0
- package/dist/js/penrose/ship.js +216 -0
- package/dist/js/penrose/sounds.js +211 -0
- package/dist/js/penrose/voidparticle.js +55 -0
- package/dist/js/penrose/voidscene.js +258 -0
- package/dist/js/penrose/voidship.js +144 -0
- package/dist/js/penrose/wormhole.js +46 -0
- package/dist/js/pipeline.js +555 -0
- package/dist/js/plane3d.js +256 -0
- package/dist/js/platformer.js +1579 -0
- package/dist/js/scene.js +304 -0
- package/dist/js/scenes.js +320 -0
- package/dist/js/schrodinger.js +410 -0
- package/dist/js/schwarzschild.js +1015 -0
- package/dist/js/shapes.js +628 -0
- package/dist/js/space/alien.js +171 -0
- package/dist/js/space/boom.js +98 -0
- package/dist/js/space/boss.js +353 -0
- package/dist/js/space/buff.js +73 -0
- package/dist/js/space/bullet.js +102 -0
- package/dist/js/space/constants.js +85 -0
- package/dist/js/space/game.js +1884 -0
- package/dist/js/space/hud.js +112 -0
- package/dist/js/space/laserbeam.js +179 -0
- package/dist/js/space/lightning.js +277 -0
- package/dist/js/space/minion.js +192 -0
- package/dist/js/space/missile.js +212 -0
- package/dist/js/space/player.js +430 -0
- package/dist/js/space/powerup.js +90 -0
- package/dist/js/space/starfield.js +58 -0
- package/dist/js/space/starpower.js +90 -0
- package/dist/js/spacetime.js +559 -0
- package/dist/js/sphere3d.js +229 -0
- package/dist/js/sprite.js +473 -0
- package/dist/js/starfaux/config.js +118 -0
- package/dist/js/starfaux/enemy.js +353 -0
- package/dist/js/starfaux/hud.js +78 -0
- package/dist/js/starfaux/index.js +482 -0
- package/dist/js/starfaux/laser.js +182 -0
- package/dist/js/starfaux/player.js +468 -0
- package/dist/js/starfaux/terrain.js +560 -0
- package/dist/js/study001.js +275 -0
- package/dist/js/study002.js +366 -0
- package/dist/js/study003.js +331 -0
- package/dist/js/study004.js +389 -0
- package/dist/js/study005.js +209 -0
- package/dist/js/study006.js +194 -0
- package/dist/js/study007.js +192 -0
- package/dist/js/study008.js +413 -0
- package/dist/js/svgtween.js +204 -0
- package/dist/js/tde/accretiondisk.js +471 -0
- package/dist/js/tde/blackhole.js +219 -0
- package/dist/js/tde/blackholescene.js +209 -0
- package/dist/js/tde/config.js +59 -0
- package/dist/js/tde/index.js +820 -0
- package/dist/js/tde/jets.js +290 -0
- package/dist/js/tde/lensedstarfield.js +154 -0
- package/dist/js/tde/tdestar.js +297 -0
- package/dist/js/tde/tidalstream.js +372 -0
- package/dist/js/tde_old/blackhole.obj.js +354 -0
- package/dist/js/tde_old/debris.obj.js +791 -0
- package/dist/js/tde_old/flare.obj.js +239 -0
- package/dist/js/tde_old/index.js +448 -0
- package/dist/js/tde_old/star.obj.js +812 -0
- package/dist/js/tetris/config.js +157 -0
- package/dist/js/tetris/grid.js +286 -0
- package/dist/js/tetris/index.js +1195 -0
- package/dist/js/tetris/renderer.js +634 -0
- package/dist/js/tetris/tetrominos.js +280 -0
- package/dist/js/tiles.js +312 -0
- package/dist/js/tweendemo.js +79 -0
- package/dist/js/visibility.js +102 -0
- package/dist/kerr.html +28 -0
- package/dist/lavalamp.html +27 -0
- package/dist/layouts.html +37 -0
- package/dist/logo.svg +4 -0
- package/dist/loop.html +84 -0
- package/dist/mondrian.html +32 -0
- package/dist/og_image.png +0 -0
- package/dist/opacity.html +36 -0
- package/dist/painter.html +39 -0
- package/dist/particles-showcase.html +28 -0
- package/dist/particles.html +24 -0
- package/dist/patterns.html +33 -0
- package/dist/penrose-game.html +31 -0
- package/dist/pipeline.html +737 -0
- package/dist/plane3d.html +24 -0
- package/dist/platformer.html +43 -0
- package/dist/scene.html +33 -0
- package/dist/scenes.html +96 -0
- package/dist/schrodinger.html +27 -0
- package/dist/schwarzschild.html +27 -0
- package/dist/shapes.html +16 -0
- package/dist/space.html +85 -0
- package/dist/spacetime.html +27 -0
- package/dist/sphere3d.html +24 -0
- package/dist/sprite.html +18 -0
- package/dist/starfaux.html +22 -0
- package/dist/study001.html +23 -0
- package/dist/study002.html +23 -0
- package/dist/study003.html +23 -0
- package/dist/study004.html +23 -0
- package/dist/study005.html +22 -0
- package/dist/study006.html +24 -0
- package/dist/study007.html +24 -0
- package/dist/study008.html +22 -0
- package/dist/svgtween.html +29 -0
- package/dist/tde.html +28 -0
- package/dist/tetris3d.html +25 -0
- package/dist/tiles.html +28 -0
- package/dist/transforms.html +400 -0
- package/dist/tween.html +45 -0
- package/dist/visibility.html +33 -0
- package/package.json +1 -1
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pipeline Demo Initializations
|
|
3
|
+
*
|
|
4
|
+
* Each function creates a demo on a specific canvas element,
|
|
5
|
+
* showcasing different layers of the rendering pipeline.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
Game,
|
|
10
|
+
Rectangle,
|
|
11
|
+
Circle,
|
|
12
|
+
Triangle,
|
|
13
|
+
TextShape,
|
|
14
|
+
Group,
|
|
15
|
+
Line,
|
|
16
|
+
Painter,
|
|
17
|
+
Motion,
|
|
18
|
+
Easing,
|
|
19
|
+
GameObject,
|
|
20
|
+
} from "/gcanvas.es.min.js";
|
|
21
|
+
|
|
22
|
+
// ─────────────────────────────────────────────────────────
|
|
23
|
+
// Demo 1: Euclidian - Basic positioning (point in space)
|
|
24
|
+
// ─────────────────────────────────────────────────────────
|
|
25
|
+
|
|
26
|
+
function initEuclidianDemo() {
|
|
27
|
+
const canvas = document.getElementById('euclidian-canvas');
|
|
28
|
+
if (!canvas) return;
|
|
29
|
+
|
|
30
|
+
const game = new Game(canvas);
|
|
31
|
+
game.backgroundColor = '#000';
|
|
32
|
+
game.enableFluidSize(canvas.parentElement);
|
|
33
|
+
game.init();
|
|
34
|
+
|
|
35
|
+
// Grid GameObject that renders the cartesian plane
|
|
36
|
+
class GridGameObject extends GameObject {
|
|
37
|
+
constructor(game, options = {}) {
|
|
38
|
+
super(game, options);
|
|
39
|
+
this.zIndex = -1000; // Render grid first (lowest z-index)
|
|
40
|
+
this.game = game;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
draw() {
|
|
44
|
+
super.draw();
|
|
45
|
+
Painter.useCtx((ctx) => {
|
|
46
|
+
const width = this.game.width;
|
|
47
|
+
const height = this.game.height;
|
|
48
|
+
const centerX = width / 2;
|
|
49
|
+
const centerY = height / 2;
|
|
50
|
+
|
|
51
|
+
// Draw grid lines (thin, 1px) - subtle grey
|
|
52
|
+
ctx.strokeStyle = '#1a1a1a';
|
|
53
|
+
ctx.lineWidth = 1;
|
|
54
|
+
|
|
55
|
+
// Vertical lines
|
|
56
|
+
for (let x = 0; x <= width; x += 5) {
|
|
57
|
+
ctx.beginPath();
|
|
58
|
+
ctx.moveTo(x, 0);
|
|
59
|
+
ctx.lineTo(x, height);
|
|
60
|
+
ctx.stroke();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Horizontal lines
|
|
64
|
+
for (let y = 0; y <= height; y += 5) {
|
|
65
|
+
ctx.beginPath();
|
|
66
|
+
ctx.moveTo(0, y);
|
|
67
|
+
ctx.lineTo(width, y);
|
|
68
|
+
ctx.stroke();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Draw center axes (terminal green)
|
|
72
|
+
ctx.strokeStyle = '#0f0';
|
|
73
|
+
ctx.lineWidth = 1;
|
|
74
|
+
ctx.beginPath();
|
|
75
|
+
// Vertical axis
|
|
76
|
+
ctx.moveTo(centerX, 0);
|
|
77
|
+
ctx.lineTo(centerX, height);
|
|
78
|
+
// Horizontal axis
|
|
79
|
+
ctx.moveTo(0, centerY);
|
|
80
|
+
ctx.lineTo(width, centerY);
|
|
81
|
+
ctx.stroke();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Create a point (circle) representing the Euclidian position
|
|
87
|
+
const point = new Circle(6, {
|
|
88
|
+
x: 100,
|
|
89
|
+
y: 100,
|
|
90
|
+
color: '#333',
|
|
91
|
+
stroke: '#0f0',
|
|
92
|
+
lineWidth: 1
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// Create text labels showing coordinates
|
|
96
|
+
const coordLabel = new TextShape('(100, 100)', {
|
|
97
|
+
x: 100,
|
|
98
|
+
y: 100,
|
|
99
|
+
color: '#0f0',
|
|
100
|
+
font: '12px monospace',
|
|
101
|
+
align: 'center',
|
|
102
|
+
baseline: 'top',
|
|
103
|
+
opacity: 0.9
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Create and add grid to pipeline
|
|
107
|
+
const grid = new GridGameObject(game);
|
|
108
|
+
|
|
109
|
+
// Animate the point moving around
|
|
110
|
+
let animTime = 0;
|
|
111
|
+
const originalUpdate = game.update.bind(game);
|
|
112
|
+
|
|
113
|
+
game.update = function(dt) {
|
|
114
|
+
originalUpdate(dt);
|
|
115
|
+
animTime += dt;
|
|
116
|
+
|
|
117
|
+
const centerX = game.width / 2;
|
|
118
|
+
const centerY = game.height / 2;
|
|
119
|
+
|
|
120
|
+
// Move point in a circular pattern
|
|
121
|
+
const radius = Math.min(game.width, game.height) * 0.2;
|
|
122
|
+
point.x = centerX + Math.cos(animTime * 0.8) * radius;
|
|
123
|
+
point.y = centerY + Math.sin(animTime * 0.8) * radius;
|
|
124
|
+
|
|
125
|
+
// Update coordinate label
|
|
126
|
+
coordLabel.x = point.x;
|
|
127
|
+
coordLabel.y = point.y + 15; // Position below the point
|
|
128
|
+
coordLabel.text = `(${Math.round(point.x)}, ${Math.round(point.y)})`;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// Add objects to pipeline (grid first so it renders behind)
|
|
132
|
+
game.pipeline.add(grid);
|
|
133
|
+
game.pipeline.add(point);
|
|
134
|
+
game.pipeline.add(coordLabel);
|
|
135
|
+
game.start();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ─────────────────────────────────────────────────────────
|
|
139
|
+
// Demo 2: Geometry2d - Bounds and constraints
|
|
140
|
+
// ─────────────────────────────────────────────────────────
|
|
141
|
+
|
|
142
|
+
function initGeometry2dDemo() {
|
|
143
|
+
const canvas = document.getElementById('geometry2d-canvas');
|
|
144
|
+
if (!canvas) return;
|
|
145
|
+
|
|
146
|
+
const game = new Game(canvas);
|
|
147
|
+
game.backgroundColor = '#000';
|
|
148
|
+
game.enableFluidSize(canvas.parentElement);
|
|
149
|
+
game.init();
|
|
150
|
+
|
|
151
|
+
let animTime = 0;
|
|
152
|
+
const originalUpdate = game.update.bind(game);
|
|
153
|
+
|
|
154
|
+
// Create a constrained shape (positioned relative to game center)
|
|
155
|
+
let constrainedShape, constraintBounds;
|
|
156
|
+
|
|
157
|
+
game.update = function(dt) {
|
|
158
|
+
originalUpdate(dt);
|
|
159
|
+
|
|
160
|
+
// Initialize shapes on first update when game dimensions are available
|
|
161
|
+
if (!constrainedShape) {
|
|
162
|
+
const centerX = game.width / 2;
|
|
163
|
+
const centerY = game.height / 2;
|
|
164
|
+
const constraintSize = Math.min(game.width, game.height) * 0.3;
|
|
165
|
+
|
|
166
|
+
constrainedShape = new Rectangle({
|
|
167
|
+
x: centerX,
|
|
168
|
+
y: centerY,
|
|
169
|
+
width: 50,
|
|
170
|
+
height: 30,
|
|
171
|
+
minX: centerX - constraintSize / 2,
|
|
172
|
+
maxX: centerX + constraintSize / 2,
|
|
173
|
+
minY: centerY - constraintSize / 2,
|
|
174
|
+
maxY: centerY + constraintSize / 2,
|
|
175
|
+
crisp: true,
|
|
176
|
+
color: '#333',
|
|
177
|
+
stroke: '#0f0',
|
|
178
|
+
lineWidth: 1,
|
|
179
|
+
debug: false
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
constraintBounds = new Rectangle({
|
|
183
|
+
x: centerX,
|
|
184
|
+
y: centerY,
|
|
185
|
+
width: constraintSize,
|
|
186
|
+
height: constraintSize,
|
|
187
|
+
color: null,
|
|
188
|
+
stroke: '#0f0',
|
|
189
|
+
lineWidth: 1,
|
|
190
|
+
debug: false
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
game.pipeline.add(constraintBounds);
|
|
194
|
+
game.pipeline.add(constrainedShape);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
animTime += dt;
|
|
198
|
+
const centerX = game.width / 2;
|
|
199
|
+
const centerY = game.height / 2;
|
|
200
|
+
const constraintSize = Math.min(game.width, game.height) * 0.3;
|
|
201
|
+
|
|
202
|
+
// Update constraints dynamically
|
|
203
|
+
constrainedShape.minX = centerX - constraintSize / 2;
|
|
204
|
+
constrainedShape.maxX = centerX + constraintSize / 2;
|
|
205
|
+
constrainedShape.minY = centerY - constraintSize / 2;
|
|
206
|
+
constrainedShape.maxY = centerY + constraintSize / 2;
|
|
207
|
+
|
|
208
|
+
// Try to move outside constraints - will be constrained
|
|
209
|
+
const radius = constraintSize * 0.6;
|
|
210
|
+
constrainedShape.x = centerX + Math.sin(animTime * 0.5) * radius;
|
|
211
|
+
constrainedShape.y = centerY + Math.cos(animTime * 0.5) * radius;
|
|
212
|
+
constrainedShape.update(); // Apply constraints
|
|
213
|
+
|
|
214
|
+
// Update constraint bounds visualization
|
|
215
|
+
constraintBounds.x = centerX;
|
|
216
|
+
constraintBounds.y = centerY;
|
|
217
|
+
constraintBounds.width = constraintSize;
|
|
218
|
+
constraintBounds.height = constraintSize;
|
|
219
|
+
|
|
220
|
+
// Show actual bounds of the constrained shape
|
|
221
|
+
const bounds = constrainedShape.getBounds();
|
|
222
|
+
// Convert top-left bounds to center coordinates for Rectangle
|
|
223
|
+
constraintBounds.x = bounds.x + bounds.width / 2;
|
|
224
|
+
constraintBounds.y = bounds.y + bounds.height / 2;
|
|
225
|
+
constraintBounds.width = bounds.width;
|
|
226
|
+
constraintBounds.height = bounds.height;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
game.start();
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// ─────────────────────────────────────────────────────────
|
|
233
|
+
// Demo 3: Renderable - Opacity and shadows
|
|
234
|
+
// ─────────────────────────────────────────────────────────
|
|
235
|
+
|
|
236
|
+
function initRenderableDemo() {
|
|
237
|
+
const canvas = document.getElementById('renderable-canvas');
|
|
238
|
+
if (!canvas) return;
|
|
239
|
+
|
|
240
|
+
const game = new Game(canvas);
|
|
241
|
+
game.backgroundColor = '#000';
|
|
242
|
+
game.enableFluidSize(canvas.parentElement);
|
|
243
|
+
game.init();
|
|
244
|
+
|
|
245
|
+
let shape1, shape2, shape3;
|
|
246
|
+
let animTime = 0;
|
|
247
|
+
const originalUpdate = game.update.bind(game);
|
|
248
|
+
|
|
249
|
+
game.update = function(dt) {
|
|
250
|
+
originalUpdate(dt);
|
|
251
|
+
|
|
252
|
+
// Initialize shapes on first update when game dimensions are available
|
|
253
|
+
if (!shape1) {
|
|
254
|
+
const centerX = game.width / 2;
|
|
255
|
+
const centerY = game.height / 2;
|
|
256
|
+
const spacing = Math.min(game.width, game.height) * 0.25;
|
|
257
|
+
|
|
258
|
+
shape1 = new Rectangle({
|
|
259
|
+
x: centerX - spacing,
|
|
260
|
+
y: centerY,
|
|
261
|
+
width: 50,
|
|
262
|
+
height: 30,
|
|
263
|
+
visible: true,
|
|
264
|
+
opacity: 0.8,
|
|
265
|
+
shadowColor: 'rgba(0,255,0,0.3)',
|
|
266
|
+
shadowBlur: 8,
|
|
267
|
+
shadowOffsetX: 2,
|
|
268
|
+
shadowOffsetY: 2,
|
|
269
|
+
color: '#1a1a1a',
|
|
270
|
+
stroke: '#0f0',
|
|
271
|
+
lineWidth: 1
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
shape2 = new Circle(25, {
|
|
275
|
+
x: centerX,
|
|
276
|
+
y: centerY,
|
|
277
|
+
opacity: 0.7,
|
|
278
|
+
shadowColor: 'rgba(0,255,0,0.3)',
|
|
279
|
+
shadowBlur: 10,
|
|
280
|
+
shadowOffsetX: 3,
|
|
281
|
+
shadowOffsetY: 3,
|
|
282
|
+
color: '#2a2a2a',
|
|
283
|
+
stroke: '#0f0',
|
|
284
|
+
lineWidth: 1
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
shape3 = new Triangle({
|
|
288
|
+
x: centerX + spacing,
|
|
289
|
+
y: centerY,
|
|
290
|
+
size: 30,
|
|
291
|
+
opacity: 0.9,
|
|
292
|
+
shadowColor: 'rgba(0,255,0,0.3)',
|
|
293
|
+
shadowBlur: 8,
|
|
294
|
+
shadowOffsetX: -2,
|
|
295
|
+
shadowOffsetY: 2,
|
|
296
|
+
color: '#1a1a1a',
|
|
297
|
+
stroke: '#0f0',
|
|
298
|
+
lineWidth: 1
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
game.pipeline.add(shape1);
|
|
302
|
+
game.pipeline.add(shape2);
|
|
303
|
+
game.pipeline.add(shape3);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
animTime += dt;
|
|
307
|
+
shape1.opacity = 0.5 + Math.sin(animTime * 2) * 0.3;
|
|
308
|
+
shape2.opacity = 0.3 + Math.cos(animTime * 1.5) * 0.4;
|
|
309
|
+
shape3.opacity = 0.7 + Math.sin(animTime * 1.8) * 0.2;
|
|
310
|
+
};
|
|
311
|
+
game.start();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// ─────────────────────────────────────────────────────────
|
|
315
|
+
// Demo 4: Transformable - Rotation and scaling
|
|
316
|
+
// ─────────────────────────────────────────────────────────
|
|
317
|
+
|
|
318
|
+
function initTransformableDemo() {
|
|
319
|
+
const canvas = document.getElementById('transformable-canvas');
|
|
320
|
+
if (!canvas) return;
|
|
321
|
+
|
|
322
|
+
const game = new Game(canvas);
|
|
323
|
+
game.backgroundColor = '#000';
|
|
324
|
+
game.enableFluidSize(canvas.parentElement);
|
|
325
|
+
game.init();
|
|
326
|
+
|
|
327
|
+
let shape1, shape2, shape3;
|
|
328
|
+
let animTime = 0;
|
|
329
|
+
const originalUpdate = game.update.bind(game);
|
|
330
|
+
|
|
331
|
+
game.update = function(dt) {
|
|
332
|
+
originalUpdate(dt);
|
|
333
|
+
|
|
334
|
+
// Initialize shapes on first update when game dimensions are available
|
|
335
|
+
if (!shape1) {
|
|
336
|
+
const centerX = game.width / 2;
|
|
337
|
+
const centerY = game.height / 2;
|
|
338
|
+
const spacing = Math.min(game.width, game.height) * 0.25;
|
|
339
|
+
|
|
340
|
+
shape1 = new Rectangle({
|
|
341
|
+
x: centerX - spacing,
|
|
342
|
+
y: centerY,
|
|
343
|
+
width: 50,
|
|
344
|
+
height: 30,
|
|
345
|
+
rotation: Math.PI / 4, // 45 degrees
|
|
346
|
+
scaleX: 1.5,
|
|
347
|
+
scaleY: 0.8,
|
|
348
|
+
color: '#1a1a1a',
|
|
349
|
+
stroke: '#0f0',
|
|
350
|
+
lineWidth: 1
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
shape2 = new Circle(20, {
|
|
354
|
+
x: centerX,
|
|
355
|
+
y: centerY,
|
|
356
|
+
rotation: 0,
|
|
357
|
+
scaleX: 1.2,
|
|
358
|
+
scaleY: 1.2,
|
|
359
|
+
color: '#2a2a2a',
|
|
360
|
+
stroke: '#0f0',
|
|
361
|
+
lineWidth: 1
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
shape3 = new Triangle({
|
|
365
|
+
x: centerX + spacing,
|
|
366
|
+
y: centerY,
|
|
367
|
+
size: 25,
|
|
368
|
+
rotation: Math.PI / 6, // 30 degrees
|
|
369
|
+
scaleX: 2.0,
|
|
370
|
+
scaleY: 2.0,
|
|
371
|
+
color: '#1a1a1a',
|
|
372
|
+
stroke: '#0f0',
|
|
373
|
+
lineWidth: 1
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
game.pipeline.add(shape1);
|
|
377
|
+
game.pipeline.add(shape2);
|
|
378
|
+
game.pipeline.add(shape3);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
animTime += dt;
|
|
382
|
+
shape1.rotation = Math.PI / 4 + Math.sin(animTime) * 0.3;
|
|
383
|
+
shape1.scaleX = 1.5 + Math.sin(animTime * 2) * 0.3;
|
|
384
|
+
shape1.scaleY = 0.8 + Math.cos(animTime * 2) * 0.2;
|
|
385
|
+
|
|
386
|
+
shape2.rotation = animTime * 0.5;
|
|
387
|
+
shape2.scaleX = 1.2 + Math.sin(animTime * 1.5) * 0.3;
|
|
388
|
+
shape2.scaleY = 1.2 + Math.sin(animTime * 1.5) * 0.3;
|
|
389
|
+
|
|
390
|
+
shape3.rotation = Math.PI / 6 + animTime * 0.8;
|
|
391
|
+
shape3.scaleX = 2.0 + Math.cos(animTime * 1.2) * 0.4;
|
|
392
|
+
shape3.scaleY = 2.0 + Math.cos(animTime * 1.2) * 0.4;
|
|
393
|
+
};
|
|
394
|
+
game.start();
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// ─────────────────────────────────────────────────────────
|
|
398
|
+
// Demo 5: Shape - Styling properties (fill, stroke)
|
|
399
|
+
// ─────────────────────────────────────────────────────────
|
|
400
|
+
|
|
401
|
+
function initShapeDemo() {
|
|
402
|
+
const canvas = document.getElementById('shape-canvas');
|
|
403
|
+
if (!canvas) return;
|
|
404
|
+
|
|
405
|
+
const game = new Game(canvas);
|
|
406
|
+
game.backgroundColor = '#000';
|
|
407
|
+
game.enableFluidSize(canvas.parentElement);
|
|
408
|
+
game.init();
|
|
409
|
+
|
|
410
|
+
let rect, circle, triangle;
|
|
411
|
+
const originalUpdate = game.update.bind(game);
|
|
412
|
+
|
|
413
|
+
game.update = function(dt) {
|
|
414
|
+
originalUpdate(dt);
|
|
415
|
+
|
|
416
|
+
// Initialize shapes on first update when game dimensions are available
|
|
417
|
+
if (!rect) {
|
|
418
|
+
const centerX = game.width / 2;
|
|
419
|
+
const centerY = game.height / 2;
|
|
420
|
+
const spacing = Math.min(game.width, game.height) * 0.25;
|
|
421
|
+
|
|
422
|
+
rect = new Rectangle({
|
|
423
|
+
x: centerX - spacing,
|
|
424
|
+
y: centerY,
|
|
425
|
+
width: 50,
|
|
426
|
+
height: 30,
|
|
427
|
+
color: '#1a1a1a',
|
|
428
|
+
stroke: '#0f0',
|
|
429
|
+
lineWidth: 1,
|
|
430
|
+
lineJoin: 'miter',
|
|
431
|
+
lineCap: 'butt'
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
circle = new Circle(25, {
|
|
435
|
+
x: centerX,
|
|
436
|
+
y: centerY,
|
|
437
|
+
color: '#2a2a2a',
|
|
438
|
+
stroke: '#0f0',
|
|
439
|
+
lineWidth: 1,
|
|
440
|
+
lineJoin: 'round',
|
|
441
|
+
lineCap: 'round'
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
triangle = new Triangle({
|
|
445
|
+
x: centerX + spacing,
|
|
446
|
+
y: centerY,
|
|
447
|
+
size: 30,
|
|
448
|
+
color: '#1a1a1a',
|
|
449
|
+
stroke: '#0f0',
|
|
450
|
+
lineWidth: 1,
|
|
451
|
+
lineJoin: 'miter',
|
|
452
|
+
lineCap: 'butt'
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
game.pipeline.add(rect);
|
|
456
|
+
game.pipeline.add(circle);
|
|
457
|
+
game.pipeline.add(triangle);
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
game.start();
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// ─────────────────────────────────────────────────────────
|
|
464
|
+
// Demo 6: Group - Composing shapes together
|
|
465
|
+
// ─────────────────────────────────────────────────────────
|
|
466
|
+
|
|
467
|
+
function initGroupDemo() {
|
|
468
|
+
const canvas = document.getElementById('group-canvas');
|
|
469
|
+
if (!canvas) return;
|
|
470
|
+
|
|
471
|
+
const game = new Game(canvas);
|
|
472
|
+
game.backgroundColor = '#000';
|
|
473
|
+
game.enableFluidSize(canvas.parentElement);
|
|
474
|
+
game.init();
|
|
475
|
+
|
|
476
|
+
let group;
|
|
477
|
+
let animTime = 0;
|
|
478
|
+
const originalUpdate = game.update.bind(game);
|
|
479
|
+
|
|
480
|
+
game.update = function(dt) {
|
|
481
|
+
originalUpdate(dt);
|
|
482
|
+
|
|
483
|
+
// Initialize group on first update when game dimensions are available
|
|
484
|
+
if (!group) {
|
|
485
|
+
const centerX = game.width / 2;
|
|
486
|
+
const centerY = game.height / 2;
|
|
487
|
+
|
|
488
|
+
// Create a Group to hold multiple shapes
|
|
489
|
+
group = new Group({
|
|
490
|
+
x: centerX,
|
|
491
|
+
y: centerY
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// Add shapes to the group - organized geometrically
|
|
495
|
+
const rect = new Rectangle({
|
|
496
|
+
width: 100,
|
|
497
|
+
height: 50,
|
|
498
|
+
color: '#1a1a1a',
|
|
499
|
+
stroke: '#0f0',
|
|
500
|
+
lineWidth: 1
|
|
501
|
+
});
|
|
502
|
+
|
|
503
|
+
const circle = new Circle(25, {
|
|
504
|
+
x: 50,
|
|
505
|
+
y: 0,
|
|
506
|
+
color: '#2a2a2a',
|
|
507
|
+
stroke: '#0f0',
|
|
508
|
+
lineWidth: 1
|
|
509
|
+
});
|
|
510
|
+
|
|
511
|
+
const text = new TextShape('GROUP', {
|
|
512
|
+
x: 0,
|
|
513
|
+
y: 0,
|
|
514
|
+
color: '#0f0',
|
|
515
|
+
align: 'center',
|
|
516
|
+
baseline: 'middle',
|
|
517
|
+
font: '14px monospace'
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
// Add shapes to the group
|
|
521
|
+
group.add(rect);
|
|
522
|
+
group.add(circle);
|
|
523
|
+
group.add(text);
|
|
524
|
+
|
|
525
|
+
// Set initial transformations
|
|
526
|
+
group.rotation = Math.PI / 6; // 30 degrees
|
|
527
|
+
group.scaleX = 1.5;
|
|
528
|
+
group.scaleY = 1.5;
|
|
529
|
+
group.opacity = 0.7;
|
|
530
|
+
|
|
531
|
+
game.pipeline.add(group);
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
animTime += dt;
|
|
535
|
+
group.rotation = Math.PI / 6 + Math.sin(animTime * 0.5) * 0.3;
|
|
536
|
+
group.scaleX = 1.5 + Math.sin(animTime * 1.2) * 0.2;
|
|
537
|
+
group.scaleY = 1.5 + Math.sin(animTime * 1.2) * 0.2;
|
|
538
|
+
group.opacity = 0.7 + Math.cos(animTime * 0.8) * 0.2;
|
|
539
|
+
};
|
|
540
|
+
game.start();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// ─────────────────────────────────────────────────────────
|
|
544
|
+
// Initialize all demos on page load
|
|
545
|
+
// ─────────────────────────────────────────────────────────
|
|
546
|
+
|
|
547
|
+
window.addEventListener('load', () => {
|
|
548
|
+
initEuclidianDemo();
|
|
549
|
+
initGeometry2dDemo();
|
|
550
|
+
initRenderableDemo();
|
|
551
|
+
initTransformableDemo();
|
|
552
|
+
initShapeDemo();
|
|
553
|
+
initGroupDemo();
|
|
554
|
+
});
|
|
555
|
+
|