@basementuniverse/particles-2d 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/.prettierrc +5 -0
- package/.vscode/settings.json +17 -0
- package/LICENSE +7 -0
- package/README.md +347 -0
- package/build/index.d.ts +357 -0
- package/build/index.js +129 -0
- package/package.json +32 -0
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { vec2 } from '@basementuniverse/vec';
|
|
2
|
+
export type RandomRange<T extends number | vec2 = number> = {
|
|
3
|
+
min: T;
|
|
4
|
+
max: T;
|
|
5
|
+
};
|
|
6
|
+
export type Color = {
|
|
7
|
+
r: number;
|
|
8
|
+
g: number;
|
|
9
|
+
b: number;
|
|
10
|
+
a?: number;
|
|
11
|
+
};
|
|
12
|
+
export declare class ParticleSystem {
|
|
13
|
+
particles: Particle[];
|
|
14
|
+
emitters: Emitter[];
|
|
15
|
+
attractors: Attractor[];
|
|
16
|
+
forceFields: ForceField[];
|
|
17
|
+
colliders: Collider[];
|
|
18
|
+
update(dt: number): void;
|
|
19
|
+
draw(context: CanvasRenderingContext2D): void;
|
|
20
|
+
}
|
|
21
|
+
declare const PARTICLE_DEFAULT_UPDATE_TYPES: string[];
|
|
22
|
+
type ParticleDefaultUpdateTypes = (typeof PARTICLE_DEFAULT_UPDATE_TYPES)[number][];
|
|
23
|
+
declare const PARTICLE_DEFAULT_DRAW_TYPES: string[];
|
|
24
|
+
type ParticleDefaultDrawTypes = (typeof PARTICLE_DEFAULT_DRAW_TYPES)[number][];
|
|
25
|
+
export type ParticleOptions = {
|
|
26
|
+
/**
|
|
27
|
+
* Should this particle be affected by attractors
|
|
28
|
+
*/
|
|
29
|
+
useAttractors: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Should this particle be affected by force fields
|
|
32
|
+
*/
|
|
33
|
+
useForceFields: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Should this particle be affected by colliders
|
|
36
|
+
*/
|
|
37
|
+
useColliders: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* What kind of default update logic to apply. This can be 'all', 'none', or
|
|
40
|
+
* an array of specific updates to apply:
|
|
41
|
+
*
|
|
42
|
+
* - 'none': no default update, only custom updates will be applied
|
|
43
|
+
* - 'all': apply all updates, including custom updates if provided
|
|
44
|
+
* - 'age': apply age updates and dispose when lifespan is reached
|
|
45
|
+
* - 'physics': apply physics updates (attractors, force fields, colliders)
|
|
46
|
+
* - 'direction': apply direction updates (calculate rotation based on
|
|
47
|
+
* velocity)
|
|
48
|
+
* - 'position': apply position updates (integrate velocity over time)
|
|
49
|
+
*/
|
|
50
|
+
defaultUpdates: 'none' | 'all' | ParticleDefaultUpdateTypes;
|
|
51
|
+
update?: (system: ParticleSystem, dt: number) => void;
|
|
52
|
+
/**
|
|
53
|
+
* What kind of default rendering logic to apply. This can be 'all', 'none',
|
|
54
|
+
* or an array of specific draws to apply:
|
|
55
|
+
*
|
|
56
|
+
* - 'none': no default rendering, only custom rendering will be applied
|
|
57
|
+
* - 'all': apply all rendering logic, including custom rendering if provided
|
|
58
|
+
* - 'transforms': apply basic translation transform, and rotation transform
|
|
59
|
+
* if using 'image' style
|
|
60
|
+
* - 'fade': apply fade in/out effects based on particle age
|
|
61
|
+
* - 'styles': render particles using one of the default styles (e.g. 'dot',
|
|
62
|
+
* 'line', etc.)
|
|
63
|
+
*/
|
|
64
|
+
defaultDraws: 'none' | 'all' | ParticleDefaultDrawTypes;
|
|
65
|
+
/**
|
|
66
|
+
* Called before default style rendering, useful for setting context state
|
|
67
|
+
* (e.g. shadow, global alpha, etc.) before drawing particles
|
|
68
|
+
*/
|
|
69
|
+
preDraw?: (system: ParticleSystem, context: CanvasRenderingContext2D) => void;
|
|
70
|
+
/**
|
|
71
|
+
* Called after default style rendering, useful for rendering additional
|
|
72
|
+
* effects or overlays after default styles have been drawn
|
|
73
|
+
*/
|
|
74
|
+
postDraw?: (system: ParticleSystem, context: CanvasRenderingContext2D) => void;
|
|
75
|
+
};
|
|
76
|
+
type GlowStyle = {
|
|
77
|
+
color: Color | string | Color[] | string[];
|
|
78
|
+
amount: number;
|
|
79
|
+
};
|
|
80
|
+
type FadeStyle = {
|
|
81
|
+
in: number;
|
|
82
|
+
out: number;
|
|
83
|
+
};
|
|
84
|
+
export type ParticleStyle = ({
|
|
85
|
+
style: 'dot';
|
|
86
|
+
color: Color | string | Color[] | string[];
|
|
87
|
+
glow?: GlowStyle;
|
|
88
|
+
} | {
|
|
89
|
+
style: 'radial';
|
|
90
|
+
color: Color | string | Color[] | string[];
|
|
91
|
+
} | {
|
|
92
|
+
style: 'line';
|
|
93
|
+
color: Color | string | Color[] | string[];
|
|
94
|
+
rotationOffset?: number;
|
|
95
|
+
glow?: GlowStyle;
|
|
96
|
+
} | {
|
|
97
|
+
style: 'image';
|
|
98
|
+
image: HTMLImageElement;
|
|
99
|
+
rotationOffset?: number;
|
|
100
|
+
}) & {
|
|
101
|
+
fade?: FadeStyle;
|
|
102
|
+
};
|
|
103
|
+
export declare class Particle {
|
|
104
|
+
/**
|
|
105
|
+
* Initial position of the particle
|
|
106
|
+
*/
|
|
107
|
+
position: vec2;
|
|
108
|
+
/**
|
|
109
|
+
* Initial velocity of the particle
|
|
110
|
+
*/
|
|
111
|
+
velocity: vec2;
|
|
112
|
+
/**
|
|
113
|
+
* Size of the particle. This is used differently based on the style:
|
|
114
|
+
*
|
|
115
|
+
* - 'dot' style: we use the maximum of x and y as the radius
|
|
116
|
+
* - 'line' style: x is the length of the line, y is the line width
|
|
117
|
+
* - 'radial' style: we use the maximum of x and y as the radius
|
|
118
|
+
* - 'image' style: x and y are the width and height of the image
|
|
119
|
+
*/
|
|
120
|
+
size: vec2;
|
|
121
|
+
/**
|
|
122
|
+
* Rotation of the particle in radians
|
|
123
|
+
*
|
|
124
|
+
* _(Note: not used for 'dot' and 'radial' styles)_
|
|
125
|
+
*
|
|
126
|
+
* If this is null, we calculate rotation based on velocity
|
|
127
|
+
*/
|
|
128
|
+
rotation: number | null;
|
|
129
|
+
/**
|
|
130
|
+
* Lifespan of the particle in seconds
|
|
131
|
+
*/
|
|
132
|
+
lifespan: number;
|
|
133
|
+
age: number;
|
|
134
|
+
style: ParticleStyle | null;
|
|
135
|
+
private actualRotation;
|
|
136
|
+
private actualColor;
|
|
137
|
+
private actualColorTransparent;
|
|
138
|
+
private actualGlowColor;
|
|
139
|
+
private options;
|
|
140
|
+
private _disposed;
|
|
141
|
+
constructor(
|
|
142
|
+
/**
|
|
143
|
+
* Initial position of the particle
|
|
144
|
+
*/
|
|
145
|
+
position: vec2,
|
|
146
|
+
/**
|
|
147
|
+
* Initial velocity of the particle
|
|
148
|
+
*/
|
|
149
|
+
velocity: vec2,
|
|
150
|
+
/**
|
|
151
|
+
* Size of the particle. This is used differently based on the style:
|
|
152
|
+
*
|
|
153
|
+
* - 'dot' style: we use the maximum of x and y as the radius
|
|
154
|
+
* - 'line' style: x is the length of the line, y is the line width
|
|
155
|
+
* - 'radial' style: we use the maximum of x and y as the radius
|
|
156
|
+
* - 'image' style: x and y are the width and height of the image
|
|
157
|
+
*/
|
|
158
|
+
size: vec2,
|
|
159
|
+
/**
|
|
160
|
+
* Rotation of the particle in radians
|
|
161
|
+
*
|
|
162
|
+
* _(Note: not used for 'dot' and 'radial' styles)_
|
|
163
|
+
*
|
|
164
|
+
* If this is null, we calculate rotation based on velocity
|
|
165
|
+
*/
|
|
166
|
+
rotation?: number | null,
|
|
167
|
+
/**
|
|
168
|
+
* Lifespan of the particle in seconds
|
|
169
|
+
*/
|
|
170
|
+
lifespan?: number,
|
|
171
|
+
/**
|
|
172
|
+
* Style options for the particle. This can be used to define a default
|
|
173
|
+
* rendering style and associated settings for the style
|
|
174
|
+
*
|
|
175
|
+
* The style can be one of:
|
|
176
|
+
*
|
|
177
|
+
* - 'dot': a simple dot with a color and optional glow
|
|
178
|
+
* - 'radial': a radial gradient with a color that fades to transparent
|
|
179
|
+
* - 'line': a line segment with a color, optional glow, and optional
|
|
180
|
+
* rotation (the rotation can be relative or absolute)
|
|
181
|
+
* - 'image': an image with an optional rotation (the rotation can be
|
|
182
|
+
* relative or absolute)
|
|
183
|
+
*
|
|
184
|
+
* If this is null, the particle will use the custom rendering hook if
|
|
185
|
+
* provided, or it will be invisible if no custom rendering is provided
|
|
186
|
+
*
|
|
187
|
+
* Omit this field or set it to undefined to use the default style
|
|
188
|
+
*/
|
|
189
|
+
style?: Partial<ParticleStyle> | null,
|
|
190
|
+
/**
|
|
191
|
+
* Provide custom update logic and rendering logic here
|
|
192
|
+
*/
|
|
193
|
+
options?: Partial<ParticleOptions>);
|
|
194
|
+
get disposed(): boolean;
|
|
195
|
+
get normalisedLifeRemaining(): number;
|
|
196
|
+
update(system: ParticleSystem, dt: number): void;
|
|
197
|
+
draw(system: ParticleSystem, context: CanvasRenderingContext2D): void;
|
|
198
|
+
}
|
|
199
|
+
export type EmitterOptions = {
|
|
200
|
+
/**
|
|
201
|
+
* Particle definition. Defines the type of particles emitted by the emitter
|
|
202
|
+
*/
|
|
203
|
+
particles: {
|
|
204
|
+
/**
|
|
205
|
+
* How to distribute initial particle positions within the emitter area:
|
|
206
|
+
*
|
|
207
|
+
* - 'uniform': uniform distribution within the area
|
|
208
|
+
* - 'normal': normal distribution from the center of the emitter area
|
|
209
|
+
* - a custom function which takes the number of particles emitted so far in
|
|
210
|
+
* the current round of emission and returns a position vector
|
|
211
|
+
*/
|
|
212
|
+
position: 'uniform' | 'normal' | ((n: number) => vec2);
|
|
213
|
+
/**
|
|
214
|
+
* The initial speed of new particles. This affects the initial velocity
|
|
215
|
+
* applied to each particle
|
|
216
|
+
*
|
|
217
|
+
* This can be one of:
|
|
218
|
+
*
|
|
219
|
+
* - a fixed speed
|
|
220
|
+
* - a range of random speeds (min and max)
|
|
221
|
+
* - a custom function which takes the number of particles emitted so far in
|
|
222
|
+
* the current round of emission and returns a speed value
|
|
223
|
+
*/
|
|
224
|
+
speed: number | RandomRange | ((n: number) => number);
|
|
225
|
+
/**
|
|
226
|
+
* The initial direction of new particles. This affects the initial velocity
|
|
227
|
+
* applied to each particle
|
|
228
|
+
*
|
|
229
|
+
* This can be one of:
|
|
230
|
+
*
|
|
231
|
+
* - a fixed angle in radians
|
|
232
|
+
* - a range of random angles (min and max)
|
|
233
|
+
* - a custom function which takes the number of particles emitted so far in
|
|
234
|
+
* the current round of emission and returns a direction value in radians
|
|
235
|
+
*/
|
|
236
|
+
direction: number | RandomRange | ((n: number) => number);
|
|
237
|
+
/**
|
|
238
|
+
* The initial size of new particles. This can be one of:
|
|
239
|
+
*
|
|
240
|
+
* - a fixed size vector (x, y)
|
|
241
|
+
* - a range of random sizes (min and max)
|
|
242
|
+
* - a custom function which takes the number of particles emitted so far in
|
|
243
|
+
* the current round of emission and returns a size vector (x, y)
|
|
244
|
+
*/
|
|
245
|
+
size: vec2 | RandomRange | ((n: number) => vec2);
|
|
246
|
+
/**
|
|
247
|
+
* The initial rotation of new particles in radians. This can be one of:
|
|
248
|
+
*
|
|
249
|
+
* - a fixed rotation in radians
|
|
250
|
+
* - a range of random rotations (min and max)
|
|
251
|
+
* - a custom function which takes the number of particles emitted so far in
|
|
252
|
+
* the current round of emission and returns a rotation value in radians
|
|
253
|
+
* - null, meaning the particles' rotation will be calculated based on their
|
|
254
|
+
* velocity vector
|
|
255
|
+
*/
|
|
256
|
+
rotation: number | RandomRange | ((n: number) => number) | null;
|
|
257
|
+
/**
|
|
258
|
+
* The lifespan of new particles in seconds. This can be one of:
|
|
259
|
+
*
|
|
260
|
+
* - a fixed lifespan in seconds
|
|
261
|
+
* - a range of random lifespans (min and max)
|
|
262
|
+
* - a custom function which takes the number of particles emitted so far in
|
|
263
|
+
* the current round of emission and returns a lifespan value in seconds
|
|
264
|
+
*/
|
|
265
|
+
lifespan: number | RandomRange | ((n: number) => number);
|
|
266
|
+
/**
|
|
267
|
+
* The style options for new particles
|
|
268
|
+
*/
|
|
269
|
+
style?: Partial<ParticleStyle> | null;
|
|
270
|
+
/**
|
|
271
|
+
* Additional options for the particle, such as custom update logic or
|
|
272
|
+
* rendering logic
|
|
273
|
+
*/
|
|
274
|
+
options?: Partial<ParticleOptions>;
|
|
275
|
+
};
|
|
276
|
+
/**
|
|
277
|
+
* Controls the rate at which particles are emitted. This can be one of:
|
|
278
|
+
*
|
|
279
|
+
* - 'rate': emit some number of particles per second
|
|
280
|
+
* - 'burst': emit a random number of particles at once
|
|
281
|
+
* - 'custom': provide a custom function which returns the number of particles
|
|
282
|
+
* to emit on each update
|
|
283
|
+
*/
|
|
284
|
+
emission: {
|
|
285
|
+
type: 'rate';
|
|
286
|
+
rate: number | RandomRange;
|
|
287
|
+
} | {
|
|
288
|
+
type: 'burst';
|
|
289
|
+
n: number | RandomRange;
|
|
290
|
+
delay?: number;
|
|
291
|
+
} | {
|
|
292
|
+
type: 'custom';
|
|
293
|
+
f: () => number;
|
|
294
|
+
};
|
|
295
|
+
};
|
|
296
|
+
export declare class Emitter {
|
|
297
|
+
position: vec2;
|
|
298
|
+
size: vec2;
|
|
299
|
+
lifespan: number;
|
|
300
|
+
private static readonly RANDOM_RATE_CHANGE_INTERVAL;
|
|
301
|
+
age: number;
|
|
302
|
+
totalParticlesEmitted: number;
|
|
303
|
+
private options;
|
|
304
|
+
private _disposed;
|
|
305
|
+
private currentRate;
|
|
306
|
+
private lastRateChange;
|
|
307
|
+
private particlesToEmit;
|
|
308
|
+
constructor(position: vec2, size?: vec2, lifespan?: number, options?: Partial<EmitterOptions>);
|
|
309
|
+
get disposed(): boolean;
|
|
310
|
+
update(system: ParticleSystem, dt: number): void;
|
|
311
|
+
private emitParticles;
|
|
312
|
+
private createParticle;
|
|
313
|
+
}
|
|
314
|
+
export declare class Attractor {
|
|
315
|
+
position: vec2;
|
|
316
|
+
range: number;
|
|
317
|
+
force: number;
|
|
318
|
+
falloff: number;
|
|
319
|
+
lifespan: number;
|
|
320
|
+
age: number;
|
|
321
|
+
private _disposed;
|
|
322
|
+
constructor(position: vec2, range?: number, force?: number, falloff?: number, lifespan?: number);
|
|
323
|
+
get disposed(): boolean;
|
|
324
|
+
applyForce(particle: Particle, dt: number): void;
|
|
325
|
+
update(dt: number): void;
|
|
326
|
+
}
|
|
327
|
+
export declare class ForceField {
|
|
328
|
+
force: vec2;
|
|
329
|
+
lifespan: number;
|
|
330
|
+
age: number;
|
|
331
|
+
private _disposed;
|
|
332
|
+
constructor(force?: vec2, lifespan?: number);
|
|
333
|
+
get disposed(): boolean;
|
|
334
|
+
applyForce(particle: Particle, dt: number): void;
|
|
335
|
+
update(dt: number): void;
|
|
336
|
+
}
|
|
337
|
+
export type ColliderGeometry = {
|
|
338
|
+
type: 'circle';
|
|
339
|
+
position: vec2;
|
|
340
|
+
radius: number;
|
|
341
|
+
} | {
|
|
342
|
+
type: 'rectangle';
|
|
343
|
+
position: vec2;
|
|
344
|
+
size: vec2;
|
|
345
|
+
rotation?: number;
|
|
346
|
+
} | {
|
|
347
|
+
type: 'polygon';
|
|
348
|
+
vertices: vec2[];
|
|
349
|
+
};
|
|
350
|
+
export declare class Collider {
|
|
351
|
+
geometry: ColliderGeometry;
|
|
352
|
+
restitution: number;
|
|
353
|
+
friction: number;
|
|
354
|
+
constructor(geometry: ColliderGeometry, restitution?: number, friction?: number);
|
|
355
|
+
handleCollision(particle: Particle): void;
|
|
356
|
+
}
|
|
357
|
+
export {};
|