@guinetik/gcanvas 1.0.0 → 1.0.1
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/demos/fluid-simple.html +22 -0
- package/demos/fluid.html +37 -0
- package/demos/index.html +2 -0
- package/demos/js/blob.js +18 -5
- package/demos/js/fluid-simple.js +253 -0
- package/demos/js/fluid.js +527 -0
- package/demos/js/tde/accretiondisk.js +64 -11
- package/demos/js/tde/blackholescene.js +2 -2
- package/demos/js/tde/config.js +2 -2
- package/demos/js/tde/index.js +152 -27
- package/demos/js/tde/lensedstarfield.js +32 -25
- package/demos/js/tde/tdestar.js +78 -98
- package/demos/js/tde/tidalstream.js +23 -7
- package/docs/README.md +230 -222
- package/docs/api/FluidSystem.md +173 -0
- package/docs/concepts/architecture-overview.md +204 -204
- package/docs/concepts/rendering-pipeline.md +279 -279
- package/docs/concepts/two-layer-architecture.md +229 -229
- package/docs/fluid-dynamics.md +97 -0
- package/docs/getting-started/first-game.md +354 -354
- package/docs/getting-started/installation.md +175 -157
- package/docs/modules/collision/README.md +2 -2
- package/docs/modules/fluent/README.md +6 -6
- package/docs/modules/game/README.md +303 -303
- package/docs/modules/isometric-camera.md +2 -2
- package/docs/modules/isometric.md +1 -1
- package/docs/modules/painter/README.md +328 -328
- package/docs/modules/particle/README.md +3 -3
- package/docs/modules/shapes/README.md +221 -221
- package/docs/modules/shapes/base/euclidian.md +123 -123
- package/docs/modules/shapes/base/shape.md +262 -262
- package/docs/modules/shapes/base/transformable.md +243 -243
- package/docs/modules/state/README.md +2 -2
- package/docs/modules/util/README.md +1 -1
- package/docs/modules/util/camera3d.md +3 -3
- package/docs/modules/util/scene3d.md +1 -1
- package/package.json +3 -1
- package/readme.md +19 -5
- package/src/collision/collision.js +75 -0
- package/src/game/index.js +2 -1
- package/src/game/pipeline.js +3 -3
- package/src/game/systems/FluidSystem.js +835 -0
- package/src/game/systems/index.js +11 -0
- package/src/game/ui/button.js +39 -18
- package/src/game/ui/cursor.js +14 -0
- package/src/game/ui/fps.js +12 -4
- package/src/game/ui/index.js +2 -0
- package/src/game/ui/stepper.js +549 -0
- package/src/game/ui/theme.js +121 -0
- package/src/game/ui/togglebutton.js +9 -3
- package/src/game/ui/tooltip.js +11 -4
- package/src/math/fluid.js +507 -0
- package/src/math/index.js +2 -0
- package/src/mixins/anchor.js +17 -7
- package/src/motion/tweenetik.js +16 -0
- package/src/shapes/index.js +1 -0
- package/src/util/camera3d.js +218 -12
- package/types/fluent.d.ts +361 -0
- package/types/game.d.ts +303 -0
- package/types/index.d.ts +144 -5
- package/types/math.d.ts +361 -0
- package/types/motion.d.ts +271 -0
- package/types/particle.d.ts +373 -0
- package/types/shapes.d.ts +107 -9
- package/types/util.d.ts +353 -0
- package/types/webgl.d.ts +109 -0
- package/disk_example.png +0 -0
- package/tde.png +0 -0
|
@@ -1,328 +1,328 @@
|
|
|
1
|
-
# Painter Module
|
|
2
|
-
|
|
3
|
-
> Low-level canvas drawing abstraction.
|
|
4
|
-
|
|
5
|
-
## Overview
|
|
6
|
-
|
|
7
|
-
Painter is a static utility class that wraps the Canvas 2D API. It provides centralized drawing operations and state management, used internally by all shapes.
|
|
8
|
-
|
|
9
|
-
## Quick Start
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
import { Painter } from 'gcanvas';
|
|
13
|
-
|
|
14
|
-
// Initialize with canvas context
|
|
15
|
-
const canvas = document.getElementById('canvas');
|
|
16
|
-
Painter.init(canvas.getContext('2d'));
|
|
17
|
-
|
|
18
|
-
// Draw shapes directly
|
|
19
|
-
Painter.shapes.fillCircle(200, 150, 50, 'red');
|
|
20
|
-
Painter.shapes.strokeRect(300, 100, 100, 80, 'blue', 2);
|
|
21
|
-
|
|
22
|
-
// Draw text
|
|
23
|
-
Painter.text.fill('Hello World', 400, 200, {
|
|
24
|
-
font: '24px monospace',
|
|
25
|
-
color: 'white'
|
|
26
|
-
});
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Architecture
|
|
30
|
-
|
|
31
|
-
Painter is composed of specialized sub-modules:
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
┌─────────────────────────────────────────────────────────────┐
|
|
35
|
-
│ Painter │
|
|
36
|
-
├─────────────────────────────────────────────────────────────┤
|
|
37
|
-
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
38
|
-
│ │ shapes │ │ text │ │ lines │ │
|
|
39
|
-
│ │ fillCircle │ │ fill │ │ line │ │
|
|
40
|
-
│ │ strokeRect │ │ stroke │ │ polyline │ │
|
|
41
|
-
│ │ arc │ │ measure │ │ bezier │ │
|
|
42
|
-
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
43
|
-
│ │
|
|
44
|
-
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
45
|
-
│ │ colors │ │ opacity │ │ effects │ │
|
|
46
|
-
│ │ fill │ │ push │ │ setBlendMode│ │
|
|
47
|
-
│ │ stroke │ │ pop │ │ shadow │ │
|
|
48
|
-
│ │ gradient │ │ current │ │ filter │ │
|
|
49
|
-
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
50
|
-
│ │
|
|
51
|
-
│ ┌─────────────┐ │
|
|
52
|
-
│ │ img │ │
|
|
53
|
-
│ │ draw │ │
|
|
54
|
-
│ │ crop │ │
|
|
55
|
-
│ │ pattern │ │
|
|
56
|
-
│ └─────────────┘ │
|
|
57
|
-
└─────────────────────────────────────────────────────────────┘
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## Core API
|
|
61
|
-
|
|
62
|
-
### Initialization
|
|
63
|
-
|
|
64
|
-
```js
|
|
65
|
-
Painter.init(ctx); // Set the canvas context
|
|
66
|
-
const ctx = Painter.ctx; // Get the context
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
### Canvas State
|
|
70
|
-
|
|
71
|
-
```js
|
|
72
|
-
Painter.save(); // Save canvas state
|
|
73
|
-
Painter.restore(); // Restore canvas state
|
|
74
|
-
Painter.clear(); // Clear entire canvas
|
|
75
|
-
Painter.clear(x, y, w, h); // Clear rectangle
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Transforms
|
|
79
|
-
|
|
80
|
-
```js
|
|
81
|
-
Painter.translateTo(x, y); // Move origin
|
|
82
|
-
Painter.rotate(radians); // Rotate context
|
|
83
|
-
Painter.scale(sx, sy); // Scale context
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Sub-Modules
|
|
87
|
-
|
|
88
|
-
### Painter.shapes
|
|
89
|
-
|
|
90
|
-
Drawing geometric shapes.
|
|
91
|
-
|
|
92
|
-
```js
|
|
93
|
-
// Circles
|
|
94
|
-
Painter.shapes.fillCircle(x, y, radius, color);
|
|
95
|
-
Painter.shapes.strokeCircle(x, y, radius, color, lineWidth);
|
|
96
|
-
|
|
97
|
-
// Rectangles
|
|
98
|
-
Painter.shapes.fillRect(x, y, width, height, color);
|
|
99
|
-
Painter.shapes.strokeRect(x, y, width, height, color, lineWidth);
|
|
100
|
-
|
|
101
|
-
// Rounded rectangles
|
|
102
|
-
Painter.shapes.fillRoundedRect(x, y, w, h, radius, color);
|
|
103
|
-
Painter.shapes.strokeRoundedRect(x, y, w, h, radius, color, lineWidth);
|
|
104
|
-
|
|
105
|
-
// Arcs
|
|
106
|
-
Painter.shapes.arc(x, y, radius, startAngle, endAngle, color);
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
### Painter.text
|
|
110
|
-
|
|
111
|
-
Text rendering and measurement.
|
|
112
|
-
|
|
113
|
-
```js
|
|
114
|
-
// Fill text
|
|
115
|
-
Painter.text.fill(text, x, y, {
|
|
116
|
-
font: '16px Arial',
|
|
117
|
-
color: 'white',
|
|
118
|
-
align: 'center', // left, center, right
|
|
119
|
-
baseline: 'middle' // top, middle, bottom
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
// Stroke text
|
|
123
|
-
Painter.text.stroke(text, x, y, {
|
|
124
|
-
font: '24px Arial',
|
|
125
|
-
color: 'black',
|
|
126
|
-
lineWidth: 2
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
// Measure text
|
|
130
|
-
const metrics = Painter.text.measure(text, font);
|
|
131
|
-
console.log(metrics.width);
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Painter.lines
|
|
135
|
-
|
|
136
|
-
Line and path drawing.
|
|
137
|
-
|
|
138
|
-
```js
|
|
139
|
-
// Simple line
|
|
140
|
-
Painter.lines.line(x1, y1, x2, y2, color, lineWidth);
|
|
141
|
-
|
|
142
|
-
// Polyline
|
|
143
|
-
Painter.lines.polyline([
|
|
144
|
-
{ x: 0, y: 0 },
|
|
145
|
-
{ x: 100, y: 50 },
|
|
146
|
-
{ x: 200, y: 25 }
|
|
147
|
-
], color, lineWidth);
|
|
148
|
-
|
|
149
|
-
// Bezier curve
|
|
150
|
-
Painter.lines.bezier(
|
|
151
|
-
x1, y1, // Start
|
|
152
|
-
cp1x, cp1y, // Control point 1
|
|
153
|
-
cp2x, cp2y, // Control point 2
|
|
154
|
-
x2, y2, // End
|
|
155
|
-
color, lineWidth
|
|
156
|
-
);
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Painter.colors
|
|
160
|
-
|
|
161
|
-
Fill and stroke color management.
|
|
162
|
-
|
|
163
|
-
```js
|
|
164
|
-
// Set fill style
|
|
165
|
-
Painter.colors.fill(color);
|
|
166
|
-
|
|
167
|
-
// Set stroke style
|
|
168
|
-
Painter.colors.stroke(color, lineWidth);
|
|
169
|
-
|
|
170
|
-
// Create gradient
|
|
171
|
-
const gradient = Painter.colors.linearGradient(x1, y1, x2, y2, stops);
|
|
172
|
-
// stops: [{ offset: 0, color: 'red' }, { offset: 1, color: 'blue' }]
|
|
173
|
-
|
|
174
|
-
const radial = Painter.colors.radialGradient(x, y, r1, r2, stops);
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
### Painter.opacity
|
|
178
|
-
|
|
179
|
-
Opacity stack management.
|
|
180
|
-
|
|
181
|
-
```js
|
|
182
|
-
// Push new opacity (multiplies with current)
|
|
183
|
-
Painter.opacity.pushOpacity(0.5);
|
|
184
|
-
|
|
185
|
-
// Drawing here is 50% transparent
|
|
186
|
-
|
|
187
|
-
// Pop to restore previous
|
|
188
|
-
Painter.opacity.popOpacity();
|
|
189
|
-
|
|
190
|
-
// Get current effective opacity
|
|
191
|
-
const current = Painter.opacity.currentOpacity;
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
### Painter.effects
|
|
195
|
-
|
|
196
|
-
Visual effects.
|
|
197
|
-
|
|
198
|
-
```js
|
|
199
|
-
// Blend modes
|
|
200
|
-
Painter.effects.setBlendMode('multiply');
|
|
201
|
-
Painter.effects.setBlendMode('screen');
|
|
202
|
-
Painter.effects.setBlendMode('source-over'); // default
|
|
203
|
-
|
|
204
|
-
// Shadow
|
|
205
|
-
Painter.effects.shadow(color, blur, offsetX, offsetY);
|
|
206
|
-
Painter.effects.clearShadow();
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Painter.img
|
|
210
|
-
|
|
211
|
-
Image drawing.
|
|
212
|
-
|
|
213
|
-
```js
|
|
214
|
-
// Draw image
|
|
215
|
-
Painter.img.draw(image, x, y);
|
|
216
|
-
Painter.img.draw(image, x, y, width, height);
|
|
217
|
-
|
|
218
|
-
// Draw cropped
|
|
219
|
-
Painter.img.drawCropped(
|
|
220
|
-
image,
|
|
221
|
-
sx, sy, sw, sh, // Source rectangle
|
|
222
|
-
dx, dy, dw, dh // Destination rectangle
|
|
223
|
-
);
|
|
224
|
-
|
|
225
|
-
// Create pattern
|
|
226
|
-
const pattern = Painter.img.createPattern(image, 'repeat');
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
## Usage Patterns
|
|
230
|
-
|
|
231
|
-
### Direct Drawing (No Shapes)
|
|
232
|
-
|
|
233
|
-
```js
|
|
234
|
-
Painter.init(ctx);
|
|
235
|
-
|
|
236
|
-
function draw() {
|
|
237
|
-
Painter.clear();
|
|
238
|
-
|
|
239
|
-
// Draw background
|
|
240
|
-
Painter.shapes.fillRect(0, 0, 800, 600, '#1a1a2e');
|
|
241
|
-
|
|
242
|
-
// Draw shapes
|
|
243
|
-
Painter.shapes.fillCircle(400, 300, 50, 'red');
|
|
244
|
-
|
|
245
|
-
// Draw text
|
|
246
|
-
Painter.text.fill('Score: 100', 10, 30, {
|
|
247
|
-
font: '20px Arial',
|
|
248
|
-
color: 'white'
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### With State Management
|
|
254
|
-
|
|
255
|
-
```js
|
|
256
|
-
Painter.save();
|
|
257
|
-
Painter.translateTo(400, 300);
|
|
258
|
-
Painter.rotate(Math.PI / 4);
|
|
259
|
-
Painter.shapes.fillRect(-50, -25, 100, 50, 'blue');
|
|
260
|
-
Painter.restore();
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Opacity Stacking
|
|
264
|
-
|
|
265
|
-
```js
|
|
266
|
-
Painter.opacity.pushOpacity(0.8);
|
|
267
|
-
// 80% opacity
|
|
268
|
-
Painter.shapes.fillCircle(100, 100, 50, 'red');
|
|
269
|
-
|
|
270
|
-
Painter.opacity.pushOpacity(0.5);
|
|
271
|
-
// 40% opacity (0.8 * 0.5)
|
|
272
|
-
Painter.shapes.fillCircle(150, 100, 50, 'blue');
|
|
273
|
-
Painter.opacity.popOpacity();
|
|
274
|
-
|
|
275
|
-
// Back to 80%
|
|
276
|
-
Painter.shapes.fillCircle(200, 100, 50, 'green');
|
|
277
|
-
Painter.opacity.popOpacity();
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
## When to Use Painter Directly
|
|
281
|
-
|
|
282
|
-
Most of the time, use Shape classes. Use Painter directly when:
|
|
283
|
-
|
|
284
|
-
- Drawing one-off graphics
|
|
285
|
-
- Custom shape implementations
|
|
286
|
-
- Performance-critical drawing
|
|
287
|
-
- Procedural graphics
|
|
288
|
-
- Effects not supported by shapes
|
|
289
|
-
|
|
290
|
-
## Example: Custom Shape
|
|
291
|
-
|
|
292
|
-
```js
|
|
293
|
-
class Diamond extends Shape {
|
|
294
|
-
draw() {
|
|
295
|
-
super.draw(); // Apply transforms
|
|
296
|
-
|
|
297
|
-
const hw = this.width / 2;
|
|
298
|
-
const hh = this.height / 2;
|
|
299
|
-
|
|
300
|
-
Painter.ctx.beginPath();
|
|
301
|
-
Painter.ctx.moveTo(0, -hh);
|
|
302
|
-
Painter.ctx.lineTo(hw, 0);
|
|
303
|
-
Painter.ctx.lineTo(0, hh);
|
|
304
|
-
Painter.ctx.lineTo(-hw, 0);
|
|
305
|
-
Painter.ctx.closePath();
|
|
306
|
-
|
|
307
|
-
if (this.color) {
|
|
308
|
-
Painter.colors.fill(this.color);
|
|
309
|
-
Painter.ctx.fill();
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
if (this.stroke) {
|
|
313
|
-
Painter.colors.stroke(this.stroke, this.lineWidth);
|
|
314
|
-
Painter.ctx.stroke();
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
## Related
|
|
321
|
-
|
|
322
|
-
- [Shapes Module](../shapes/README.md) - High-level shape classes
|
|
323
|
-
- [Rendering Pipeline](../../concepts/rendering-pipeline.md) - How shapes use Painter
|
|
324
|
-
|
|
325
|
-
## See Also
|
|
326
|
-
|
|
327
|
-
- [Hello World](../../getting-started/hello-world.md)
|
|
328
|
-
- [Architecture Overview](../../concepts/architecture-overview.md)
|
|
1
|
+
# Painter Module
|
|
2
|
+
|
|
3
|
+
> Low-level canvas drawing abstraction.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Painter is a static utility class that wraps the Canvas 2D API. It provides centralized drawing operations and state management, used internally by all shapes.
|
|
8
|
+
|
|
9
|
+
## Quick Start
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import { Painter } from '@guinetik/gcanvas';
|
|
13
|
+
|
|
14
|
+
// Initialize with canvas context
|
|
15
|
+
const canvas = document.getElementById('canvas');
|
|
16
|
+
Painter.init(canvas.getContext('2d'));
|
|
17
|
+
|
|
18
|
+
// Draw shapes directly
|
|
19
|
+
Painter.shapes.fillCircle(200, 150, 50, 'red');
|
|
20
|
+
Painter.shapes.strokeRect(300, 100, 100, 80, 'blue', 2);
|
|
21
|
+
|
|
22
|
+
// Draw text
|
|
23
|
+
Painter.text.fill('Hello World', 400, 200, {
|
|
24
|
+
font: '24px monospace',
|
|
25
|
+
color: 'white'
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Architecture
|
|
30
|
+
|
|
31
|
+
Painter is composed of specialized sub-modules:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
35
|
+
│ Painter │
|
|
36
|
+
├─────────────────────────────────────────────────────────────┤
|
|
37
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
38
|
+
│ │ shapes │ │ text │ │ lines │ │
|
|
39
|
+
│ │ fillCircle │ │ fill │ │ line │ │
|
|
40
|
+
│ │ strokeRect │ │ stroke │ │ polyline │ │
|
|
41
|
+
│ │ arc │ │ measure │ │ bezier │ │
|
|
42
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
43
|
+
│ │
|
|
44
|
+
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
45
|
+
│ │ colors │ │ opacity │ │ effects │ │
|
|
46
|
+
│ │ fill │ │ push │ │ setBlendMode│ │
|
|
47
|
+
│ │ stroke │ │ pop │ │ shadow │ │
|
|
48
|
+
│ │ gradient │ │ current │ │ filter │ │
|
|
49
|
+
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
|
50
|
+
│ │
|
|
51
|
+
│ ┌─────────────┐ │
|
|
52
|
+
│ │ img │ │
|
|
53
|
+
│ │ draw │ │
|
|
54
|
+
│ │ crop │ │
|
|
55
|
+
│ │ pattern │ │
|
|
56
|
+
│ └─────────────┘ │
|
|
57
|
+
└─────────────────────────────────────────────────────────────┘
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Core API
|
|
61
|
+
|
|
62
|
+
### Initialization
|
|
63
|
+
|
|
64
|
+
```js
|
|
65
|
+
Painter.init(ctx); // Set the canvas context
|
|
66
|
+
const ctx = Painter.ctx; // Get the context
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Canvas State
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
Painter.save(); // Save canvas state
|
|
73
|
+
Painter.restore(); // Restore canvas state
|
|
74
|
+
Painter.clear(); // Clear entire canvas
|
|
75
|
+
Painter.clear(x, y, w, h); // Clear rectangle
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Transforms
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
Painter.translateTo(x, y); // Move origin
|
|
82
|
+
Painter.rotate(radians); // Rotate context
|
|
83
|
+
Painter.scale(sx, sy); // Scale context
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Sub-Modules
|
|
87
|
+
|
|
88
|
+
### Painter.shapes
|
|
89
|
+
|
|
90
|
+
Drawing geometric shapes.
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
// Circles
|
|
94
|
+
Painter.shapes.fillCircle(x, y, radius, color);
|
|
95
|
+
Painter.shapes.strokeCircle(x, y, radius, color, lineWidth);
|
|
96
|
+
|
|
97
|
+
// Rectangles
|
|
98
|
+
Painter.shapes.fillRect(x, y, width, height, color);
|
|
99
|
+
Painter.shapes.strokeRect(x, y, width, height, color, lineWidth);
|
|
100
|
+
|
|
101
|
+
// Rounded rectangles
|
|
102
|
+
Painter.shapes.fillRoundedRect(x, y, w, h, radius, color);
|
|
103
|
+
Painter.shapes.strokeRoundedRect(x, y, w, h, radius, color, lineWidth);
|
|
104
|
+
|
|
105
|
+
// Arcs
|
|
106
|
+
Painter.shapes.arc(x, y, radius, startAngle, endAngle, color);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Painter.text
|
|
110
|
+
|
|
111
|
+
Text rendering and measurement.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
// Fill text
|
|
115
|
+
Painter.text.fill(text, x, y, {
|
|
116
|
+
font: '16px Arial',
|
|
117
|
+
color: 'white',
|
|
118
|
+
align: 'center', // left, center, right
|
|
119
|
+
baseline: 'middle' // top, middle, bottom
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Stroke text
|
|
123
|
+
Painter.text.stroke(text, x, y, {
|
|
124
|
+
font: '24px Arial',
|
|
125
|
+
color: 'black',
|
|
126
|
+
lineWidth: 2
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Measure text
|
|
130
|
+
const metrics = Painter.text.measure(text, font);
|
|
131
|
+
console.log(metrics.width);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Painter.lines
|
|
135
|
+
|
|
136
|
+
Line and path drawing.
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
// Simple line
|
|
140
|
+
Painter.lines.line(x1, y1, x2, y2, color, lineWidth);
|
|
141
|
+
|
|
142
|
+
// Polyline
|
|
143
|
+
Painter.lines.polyline([
|
|
144
|
+
{ x: 0, y: 0 },
|
|
145
|
+
{ x: 100, y: 50 },
|
|
146
|
+
{ x: 200, y: 25 }
|
|
147
|
+
], color, lineWidth);
|
|
148
|
+
|
|
149
|
+
// Bezier curve
|
|
150
|
+
Painter.lines.bezier(
|
|
151
|
+
x1, y1, // Start
|
|
152
|
+
cp1x, cp1y, // Control point 1
|
|
153
|
+
cp2x, cp2y, // Control point 2
|
|
154
|
+
x2, y2, // End
|
|
155
|
+
color, lineWidth
|
|
156
|
+
);
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Painter.colors
|
|
160
|
+
|
|
161
|
+
Fill and stroke color management.
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
// Set fill style
|
|
165
|
+
Painter.colors.fill(color);
|
|
166
|
+
|
|
167
|
+
// Set stroke style
|
|
168
|
+
Painter.colors.stroke(color, lineWidth);
|
|
169
|
+
|
|
170
|
+
// Create gradient
|
|
171
|
+
const gradient = Painter.colors.linearGradient(x1, y1, x2, y2, stops);
|
|
172
|
+
// stops: [{ offset: 0, color: 'red' }, { offset: 1, color: 'blue' }]
|
|
173
|
+
|
|
174
|
+
const radial = Painter.colors.radialGradient(x, y, r1, r2, stops);
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Painter.opacity
|
|
178
|
+
|
|
179
|
+
Opacity stack management.
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
// Push new opacity (multiplies with current)
|
|
183
|
+
Painter.opacity.pushOpacity(0.5);
|
|
184
|
+
|
|
185
|
+
// Drawing here is 50% transparent
|
|
186
|
+
|
|
187
|
+
// Pop to restore previous
|
|
188
|
+
Painter.opacity.popOpacity();
|
|
189
|
+
|
|
190
|
+
// Get current effective opacity
|
|
191
|
+
const current = Painter.opacity.currentOpacity;
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Painter.effects
|
|
195
|
+
|
|
196
|
+
Visual effects.
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
// Blend modes
|
|
200
|
+
Painter.effects.setBlendMode('multiply');
|
|
201
|
+
Painter.effects.setBlendMode('screen');
|
|
202
|
+
Painter.effects.setBlendMode('source-over'); // default
|
|
203
|
+
|
|
204
|
+
// Shadow
|
|
205
|
+
Painter.effects.shadow(color, blur, offsetX, offsetY);
|
|
206
|
+
Painter.effects.clearShadow();
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Painter.img
|
|
210
|
+
|
|
211
|
+
Image drawing.
|
|
212
|
+
|
|
213
|
+
```js
|
|
214
|
+
// Draw image
|
|
215
|
+
Painter.img.draw(image, x, y);
|
|
216
|
+
Painter.img.draw(image, x, y, width, height);
|
|
217
|
+
|
|
218
|
+
// Draw cropped
|
|
219
|
+
Painter.img.drawCropped(
|
|
220
|
+
image,
|
|
221
|
+
sx, sy, sw, sh, // Source rectangle
|
|
222
|
+
dx, dy, dw, dh // Destination rectangle
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
// Create pattern
|
|
226
|
+
const pattern = Painter.img.createPattern(image, 'repeat');
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Usage Patterns
|
|
230
|
+
|
|
231
|
+
### Direct Drawing (No Shapes)
|
|
232
|
+
|
|
233
|
+
```js
|
|
234
|
+
Painter.init(ctx);
|
|
235
|
+
|
|
236
|
+
function draw() {
|
|
237
|
+
Painter.clear();
|
|
238
|
+
|
|
239
|
+
// Draw background
|
|
240
|
+
Painter.shapes.fillRect(0, 0, 800, 600, '#1a1a2e');
|
|
241
|
+
|
|
242
|
+
// Draw shapes
|
|
243
|
+
Painter.shapes.fillCircle(400, 300, 50, 'red');
|
|
244
|
+
|
|
245
|
+
// Draw text
|
|
246
|
+
Painter.text.fill('Score: 100', 10, 30, {
|
|
247
|
+
font: '20px Arial',
|
|
248
|
+
color: 'white'
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### With State Management
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
Painter.save();
|
|
257
|
+
Painter.translateTo(400, 300);
|
|
258
|
+
Painter.rotate(Math.PI / 4);
|
|
259
|
+
Painter.shapes.fillRect(-50, -25, 100, 50, 'blue');
|
|
260
|
+
Painter.restore();
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Opacity Stacking
|
|
264
|
+
|
|
265
|
+
```js
|
|
266
|
+
Painter.opacity.pushOpacity(0.8);
|
|
267
|
+
// 80% opacity
|
|
268
|
+
Painter.shapes.fillCircle(100, 100, 50, 'red');
|
|
269
|
+
|
|
270
|
+
Painter.opacity.pushOpacity(0.5);
|
|
271
|
+
// 40% opacity (0.8 * 0.5)
|
|
272
|
+
Painter.shapes.fillCircle(150, 100, 50, 'blue');
|
|
273
|
+
Painter.opacity.popOpacity();
|
|
274
|
+
|
|
275
|
+
// Back to 80%
|
|
276
|
+
Painter.shapes.fillCircle(200, 100, 50, 'green');
|
|
277
|
+
Painter.opacity.popOpacity();
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## When to Use Painter Directly
|
|
281
|
+
|
|
282
|
+
Most of the time, use Shape classes. Use Painter directly when:
|
|
283
|
+
|
|
284
|
+
- Drawing one-off graphics
|
|
285
|
+
- Custom shape implementations
|
|
286
|
+
- Performance-critical drawing
|
|
287
|
+
- Procedural graphics
|
|
288
|
+
- Effects not supported by shapes
|
|
289
|
+
|
|
290
|
+
## Example: Custom Shape
|
|
291
|
+
|
|
292
|
+
```js
|
|
293
|
+
class Diamond extends Shape {
|
|
294
|
+
draw() {
|
|
295
|
+
super.draw(); // Apply transforms
|
|
296
|
+
|
|
297
|
+
const hw = this.width / 2;
|
|
298
|
+
const hh = this.height / 2;
|
|
299
|
+
|
|
300
|
+
Painter.ctx.beginPath();
|
|
301
|
+
Painter.ctx.moveTo(0, -hh);
|
|
302
|
+
Painter.ctx.lineTo(hw, 0);
|
|
303
|
+
Painter.ctx.lineTo(0, hh);
|
|
304
|
+
Painter.ctx.lineTo(-hw, 0);
|
|
305
|
+
Painter.ctx.closePath();
|
|
306
|
+
|
|
307
|
+
if (this.color) {
|
|
308
|
+
Painter.colors.fill(this.color);
|
|
309
|
+
Painter.ctx.fill();
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (this.stroke) {
|
|
313
|
+
Painter.colors.stroke(this.stroke, this.lineWidth);
|
|
314
|
+
Painter.ctx.stroke();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## Related
|
|
321
|
+
|
|
322
|
+
- [Shapes Module](../shapes/README.md) - High-level shape classes
|
|
323
|
+
- [Rendering Pipeline](../../concepts/rendering-pipeline.md) - How shapes use Painter
|
|
324
|
+
|
|
325
|
+
## See Also
|
|
326
|
+
|
|
327
|
+
- [Hello World](../../getting-started/hello-world.md)
|
|
328
|
+
- [Architecture Overview](../../concepts/architecture-overview.md)
|
|
@@ -15,7 +15,7 @@ The particle module provides a flexible system for creating visual effects like
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
17
17
|
```js
|
|
18
|
-
import { Game, ParticleSystem, ParticleEmitter, Updaters } from 'gcanvas';
|
|
18
|
+
import { Game, ParticleSystem, ParticleEmitter, Updaters } from '@guinetik/gcanvas';
|
|
19
19
|
|
|
20
20
|
class MyGame extends Game {
|
|
21
21
|
init() {
|
|
@@ -234,7 +234,7 @@ Updaters are composable functions that define particle behavior. Each updater ha
|
|
|
234
234
|
### Built-in Updaters
|
|
235
235
|
|
|
236
236
|
```js
|
|
237
|
-
import { Updaters } from 'gcanvas';
|
|
237
|
+
import { Updaters } from '@guinetik/gcanvas';
|
|
238
238
|
|
|
239
239
|
const particles = new ParticleSystem(game, {
|
|
240
240
|
updaters: [
|
|
@@ -349,7 +349,7 @@ Each particle has these properties (accessible in updaters):
|
|
|
349
349
|
For 3D particle effects, pass a Camera3D instance:
|
|
350
350
|
|
|
351
351
|
```js
|
|
352
|
-
import { Camera3D, ParticleSystem, ParticleEmitter, Updaters } from 'gcanvas';
|
|
352
|
+
import { Camera3D, ParticleSystem, ParticleEmitter, Updaters } from '@guinetik/gcanvas';
|
|
353
353
|
|
|
354
354
|
class My3DParticles extends Game {
|
|
355
355
|
init() {
|