@basmilius/sparkle 2.0.0 → 2.2.0

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.
Files changed (129) hide show
  1. package/dist/index.d.mts +1053 -28
  2. package/dist/index.d.mts.map +1 -1
  3. package/dist/index.mjs +4840 -400
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +7 -2
  6. package/src/aurora/consts.ts +3 -0
  7. package/src/aurora/index.ts +10 -0
  8. package/src/aurora/layer.ts +180 -0
  9. package/src/aurora/types.ts +13 -0
  10. package/src/balloons/consts.ts +3 -0
  11. package/src/balloons/index.ts +12 -0
  12. package/src/balloons/layer.ts +169 -0
  13. package/src/balloons/particle.ts +110 -0
  14. package/src/balloons/types.ts +14 -0
  15. package/src/bubbles/consts.ts +3 -0
  16. package/src/bubbles/index.ts +10 -0
  17. package/src/bubbles/layer.ts +246 -0
  18. package/src/bubbles/types.ts +21 -0
  19. package/src/canvas.ts +32 -1
  20. package/src/color.ts +19 -0
  21. package/src/confetti/consts.ts +13 -13
  22. package/src/confetti/index.ts +20 -2
  23. package/src/confetti/layer.ts +155 -0
  24. package/src/confetti/particle.ts +106 -0
  25. package/src/confetti/shapes.ts +104 -0
  26. package/src/confetti/types.ts +4 -1
  27. package/src/distance.ts +1 -1
  28. package/src/donuts/consts.ts +19 -0
  29. package/src/donuts/donut.ts +12 -0
  30. package/src/donuts/index.ts +9 -0
  31. package/src/donuts/layer.ts +301 -0
  32. package/src/effect.ts +107 -0
  33. package/src/fade.ts +87 -0
  34. package/src/fireflies/consts.ts +3 -0
  35. package/src/fireflies/index.ts +12 -0
  36. package/src/fireflies/layer.ts +169 -0
  37. package/src/fireflies/particle.ts +124 -0
  38. package/src/fireflies/types.ts +17 -0
  39. package/src/firepit/consts.ts +3 -0
  40. package/src/firepit/index.ts +10 -0
  41. package/src/firepit/layer.ts +193 -0
  42. package/src/firepit/types.ts +20 -0
  43. package/src/fireworks/create-explosion.ts +237 -0
  44. package/src/fireworks/explosion.ts +9 -9
  45. package/src/fireworks/firework.ts +9 -8
  46. package/src/fireworks/index.ts +19 -3
  47. package/src/fireworks/layer.ts +203 -0
  48. package/src/fireworks/spark.ts +9 -9
  49. package/src/fireworks/types.ts +2 -2
  50. package/src/glitter/consts.ts +13 -0
  51. package/src/glitter/index.ts +9 -0
  52. package/src/glitter/layer.ts +181 -0
  53. package/src/glitter/types.ts +33 -0
  54. package/src/index.ts +27 -0
  55. package/src/lanterns/consts.ts +13 -0
  56. package/src/lanterns/index.ts +9 -0
  57. package/src/lanterns/layer.ts +178 -0
  58. package/src/lanterns/types.ts +22 -0
  59. package/src/layer.ts +26 -0
  60. package/src/leaves/consts.ts +16 -0
  61. package/src/leaves/index.ts +9 -0
  62. package/src/leaves/layer.ts +258 -0
  63. package/src/leaves/types.ts +25 -0
  64. package/src/lightning/consts.ts +3 -0
  65. package/src/lightning/index.ts +11 -0
  66. package/src/lightning/layer.ts +41 -0
  67. package/src/lightning/system.ts +196 -0
  68. package/src/lightning/types.ts +20 -0
  69. package/src/matrix/consts.ts +5 -0
  70. package/src/matrix/index.ts +9 -0
  71. package/src/matrix/layer.ts +154 -0
  72. package/src/matrix/types.ts +17 -0
  73. package/src/orbits/consts.ts +13 -0
  74. package/src/orbits/index.ts +9 -0
  75. package/src/orbits/layer.ts +213 -0
  76. package/src/orbits/types.ts +27 -0
  77. package/src/particles/consts.ts +3 -0
  78. package/src/particles/index.ts +10 -0
  79. package/src/particles/layer.ts +360 -0
  80. package/src/particles/types.ts +10 -0
  81. package/src/petals/consts.ts +13 -0
  82. package/src/petals/index.ts +10 -0
  83. package/src/petals/layer.ts +174 -0
  84. package/src/petals/types.ts +15 -0
  85. package/src/plasma/consts.ts +3 -0
  86. package/src/plasma/index.ts +10 -0
  87. package/src/plasma/layer.ts +107 -0
  88. package/src/plasma/types.ts +5 -0
  89. package/src/rain/consts.ts +3 -0
  90. package/src/rain/index.ts +12 -0
  91. package/src/rain/layer.ts +194 -0
  92. package/src/rain/particle.ts +132 -0
  93. package/src/rain/types.ts +22 -0
  94. package/src/sandstorm/consts.ts +3 -0
  95. package/src/sandstorm/index.ts +10 -0
  96. package/src/sandstorm/layer.ts +152 -0
  97. package/src/sandstorm/types.ts +10 -0
  98. package/src/scene.ts +201 -0
  99. package/src/shooting-stars/index.ts +3 -0
  100. package/src/shooting-stars/system.ts +151 -0
  101. package/src/shooting-stars/types.ts +11 -0
  102. package/src/simulation-canvas.ts +83 -0
  103. package/src/snow/consts.ts +2 -2
  104. package/src/snow/index.ts +9 -2
  105. package/src/snow/{simulation.ts → layer.ts} +64 -89
  106. package/src/sparklers/consts.ts +3 -0
  107. package/src/sparklers/index.ts +16 -0
  108. package/src/sparklers/layer.ts +220 -0
  109. package/src/sparklers/particle.ts +89 -0
  110. package/src/sparklers/types.ts +13 -0
  111. package/src/stars/consts.ts +3 -0
  112. package/src/stars/index.ts +10 -0
  113. package/src/stars/layer.ts +139 -0
  114. package/src/stars/types.ts +12 -0
  115. package/src/streamers/consts.ts +14 -0
  116. package/src/streamers/index.ts +10 -0
  117. package/src/streamers/layer.ts +223 -0
  118. package/src/streamers/types.ts +14 -0
  119. package/src/trail.ts +140 -0
  120. package/src/waves/consts.ts +3 -0
  121. package/src/waves/index.ts +10 -0
  122. package/src/waves/layer.ts +164 -0
  123. package/src/waves/types.ts +10 -0
  124. package/src/wormhole/consts.ts +3 -0
  125. package/src/wormhole/index.ts +10 -0
  126. package/src/wormhole/layer.ts +197 -0
  127. package/src/wormhole/types.ts +10 -0
  128. package/src/confetti/simulation.ts +0 -221
  129. package/src/fireworks/simulation.ts +0 -493
@@ -0,0 +1,154 @@
1
+ import { hexToRGB } from '@basmilius/utils';
2
+ import { Effect } from '../effect';
3
+ import { MATRIX_CHARS, MULBERRY } from './consts';
4
+ import type { MatrixColumn, MatrixConfig } from './types';
5
+
6
+ export class Matrix extends Effect<MatrixConfig> {
7
+ readonly #scale: number;
8
+ #speed: number;
9
+ readonly #fontSize: number;
10
+ #trailLength: number;
11
+ readonly #colorRGB: [number, number, number];
12
+ #maxColumns: number;
13
+ #columns: MatrixColumn[] = [];
14
+ #respawnTimers: number[] = [];
15
+ #width: number = 960;
16
+ #height: number = 540;
17
+ #initialized: boolean = false;
18
+
19
+ constructor(config: MatrixConfig = {}) {
20
+ super();
21
+
22
+ this.#scale = config.scale ?? 1;
23
+ this.#maxColumns = config.columns ?? 40;
24
+ this.#speed = config.speed ?? 1;
25
+ this.#fontSize = (config.fontSize ?? 14) * this.#scale;
26
+ this.#trailLength = config.trailLength ?? 20;
27
+ this.#colorRGB = hexToRGB(config.color ?? '#00ff41');
28
+
29
+ if (innerWidth < 991) {
30
+ this.#maxColumns = Math.floor(this.#maxColumns / 2);
31
+ }
32
+ }
33
+
34
+ onResize(width: number, height: number): void {
35
+ this.#width = width;
36
+ this.#height = height;
37
+
38
+ if (!this.#initialized) {
39
+ this.#initialized = true;
40
+ this.#columns = [];
41
+ this.#respawnTimers = [];
42
+
43
+ const columnWidth = this.#fontSize;
44
+ const totalSlots = Math.floor(width / columnWidth);
45
+ const columnCount = Math.min(this.#maxColumns, totalSlots);
46
+
47
+ for (let i = 0; i < columnCount; ++i) {
48
+ const column = this.#createColumn(totalSlots, height);
49
+ this.#columns.push(column);
50
+ this.#respawnTimers.push(0);
51
+ }
52
+ }
53
+ }
54
+
55
+ configure(config: Partial<MatrixConfig>): void {
56
+ if (config.speed !== undefined) {
57
+ this.#speed = config.speed;
58
+ }
59
+ if (config.trailLength !== undefined) {
60
+ this.#trailLength = config.trailLength;
61
+ }
62
+ }
63
+
64
+ tick(dt: number, width: number, height: number): void {
65
+ this.#width = width;
66
+ this.#height = height;
67
+
68
+ const columnWidth = this.#fontSize;
69
+ const totalSlots = Math.floor(width / columnWidth);
70
+
71
+ for (let i = 0; i < this.#columns.length; ++i) {
72
+ if (this.#respawnTimers[i] > 0) {
73
+ this.#respawnTimers[i] -= dt;
74
+
75
+ if (this.#respawnTimers[i] <= 0) {
76
+ this.#columns[i] = this.#createColumn(totalSlots, height);
77
+ }
78
+
79
+ continue;
80
+ }
81
+
82
+ const column = this.#columns[i];
83
+
84
+ column.y += column.speed * this.#speed * dt;
85
+
86
+ for (let ci = 0; ci < column.chars.length; ++ci) {
87
+ if (MULBERRY.next() < 0.03) {
88
+ column.chars[ci] = MATRIX_CHARS[Math.floor(MULBERRY.next() * MATRIX_CHARS.length)];
89
+ }
90
+ }
91
+
92
+ const topOfTrail = column.y - (column.chars.length - 1) * this.#fontSize;
93
+
94
+ if (topOfTrail > height) {
95
+ this.#respawnTimers[i] = 10 + MULBERRY.next() * 60;
96
+ }
97
+ }
98
+ }
99
+
100
+ draw(ctx: CanvasRenderingContext2D, width: number, height: number): void {
101
+ ctx.fillStyle = 'rgb(0, 0, 0)';
102
+ ctx.fillRect(0, 0, width, height);
103
+
104
+ const [cr, cg, cb] = this.#colorRGB;
105
+
106
+ ctx.font = `${this.#fontSize}px monospace`;
107
+ ctx.textAlign = 'center';
108
+
109
+ for (const column of this.#columns) {
110
+ const charCount = column.chars.length;
111
+
112
+ for (let ci = 0; ci < charCount; ++ci) {
113
+ const charY = column.y - (charCount - 1 - ci) * this.#fontSize;
114
+
115
+ if (charY < -this.#fontSize || charY > height + this.#fontSize) {
116
+ continue;
117
+ }
118
+
119
+ const isHead = ci === charCount - 1;
120
+
121
+ if (isHead) {
122
+ const headAlpha = column.headBrightness;
123
+ ctx.fillStyle = `rgba(255, 255, 255, ${headAlpha})`;
124
+ } else {
125
+ const trailProgress = ci / (charCount - 1);
126
+ const alpha = trailProgress * 0.8 + 0.05;
127
+ ctx.fillStyle = `rgba(${cr}, ${cg}, ${cb}, ${alpha})`;
128
+ }
129
+
130
+ ctx.fillText(column.chars[ci], column.x, charY);
131
+ }
132
+ }
133
+ }
134
+
135
+ #createColumn(totalSlots: number, height: number): MatrixColumn {
136
+ const columnWidth = this.#fontSize;
137
+ const slot = Math.floor(MULBERRY.next() * totalSlots);
138
+ const length = Math.floor(this.#trailLength * 0.5 + MULBERRY.next() * this.#trailLength);
139
+ const chars: string[] = [];
140
+
141
+ for (let ci = 0; ci < length; ++ci) {
142
+ chars.push(MATRIX_CHARS[Math.floor(MULBERRY.next() * MATRIX_CHARS.length)]);
143
+ }
144
+
145
+ return {
146
+ x: slot * columnWidth + columnWidth / 2,
147
+ y: -(MULBERRY.next() * height),
148
+ speed: 1.5 + MULBERRY.next() * 3,
149
+ chars,
150
+ length,
151
+ headBrightness: 0.8 + MULBERRY.next() * 0.2
152
+ };
153
+ }
154
+ }
@@ -0,0 +1,17 @@
1
+ export interface MatrixConfig {
2
+ readonly columns?: number;
3
+ readonly speed?: number;
4
+ readonly color?: string;
5
+ readonly fontSize?: number;
6
+ readonly trailLength?: number;
7
+ readonly scale?: number;
8
+ }
9
+
10
+ export type MatrixColumn = {
11
+ x: number;
12
+ y: number;
13
+ speed: number;
14
+ chars: string[];
15
+ length: number;
16
+ headBrightness: number;
17
+ };
@@ -0,0 +1,13 @@
1
+ import { type Mulberry32, mulberry32 } from '@basmilius/utils';
2
+
3
+ export const MULBERRY: Mulberry32 = mulberry32(13);
4
+
5
+ export const ORBIT_COLORS: string[] = [
6
+ '#60a5fa', // blue
7
+ '#a78bfa', // purple
8
+ '#f472b6', // pink
9
+ '#34d399', // emerald
10
+ '#fbbf24', // amber
11
+ '#fb923c', // orange
12
+ '#38bdf8' // sky
13
+ ];
@@ -0,0 +1,9 @@
1
+ import { Orbits } from './layer';
2
+ import type { OrbitsConfig } from './types';
3
+ import type { Effect } from '../effect';
4
+
5
+ export function createOrbits(config?: OrbitsConfig): Effect<OrbitsConfig> {
6
+ return new Orbits(config);
7
+ }
8
+
9
+ export type { OrbitsConfig, OrbitalCenter, Orbiter } from './types';
@@ -0,0 +1,213 @@
1
+ import { hexToRGB } from '@basmilius/utils';
2
+ import { Effect } from '../effect';
3
+ import { MULBERRY, ORBIT_COLORS } from './consts';
4
+ import type { OrbitalCenter, Orbiter, OrbitsConfig } from './types';
5
+
6
+ export class Orbits extends Effect<OrbitsConfig> {
7
+ readonly #centerCount: number;
8
+ readonly #orbitersPerCenter: number;
9
+ #speed: number;
10
+ readonly #colors: string[];
11
+ #trailLength: number;
12
+ #showCenters: boolean;
13
+ #scale: number;
14
+ #centers: OrbitalCenter[] = [];
15
+ #orbiters: Orbiter[] = [];
16
+ #time: number = 0;
17
+ #initialized: boolean = false;
18
+
19
+ constructor(config: OrbitsConfig = {}) {
20
+ super();
21
+
22
+ this.#centerCount = config.centers ?? 3;
23
+ this.#orbitersPerCenter = config.orbitersPerCenter ?? 8;
24
+ this.#speed = config.speed ?? 1;
25
+ this.#colors = config.colors ?? ORBIT_COLORS;
26
+ this.#trailLength = config.trailLength ?? 15;
27
+ this.#showCenters = config.showCenters ?? true;
28
+ this.#scale = config.scale ?? 1;
29
+ }
30
+
31
+ onResize(_width: number, _height: number): void {
32
+ if (!this.#initialized) {
33
+ this.#initialized = true;
34
+ this.#centers = [];
35
+ this.#orbiters = [];
36
+
37
+ for (let i = 0; i < this.#centerCount; i++) {
38
+ this.#centers.push({
39
+ x: 0.15 + MULBERRY.next() * 0.7,
40
+ y: 0.15 + MULBERRY.next() * 0.7
41
+ });
42
+ }
43
+
44
+ const count = innerWidth < 991
45
+ ? Math.floor(this.#orbitersPerCenter / 2)
46
+ : this.#orbitersPerCenter;
47
+
48
+ for (let ci = 0; ci < this.#centers.length; ci++) {
49
+ for (let oi = 0; oi < count; oi++) {
50
+ this.#orbiters.push(this.#createOrbiter(ci));
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ configure(config: Partial<OrbitsConfig>): void {
57
+ if (config.speed !== undefined) {
58
+ this.#speed = config.speed;
59
+ }
60
+ if (config.trailLength !== undefined) {
61
+ this.#trailLength = config.trailLength;
62
+ }
63
+ if (config.showCenters !== undefined) {
64
+ this.#showCenters = config.showCenters;
65
+ }
66
+ if (config.scale !== undefined) {
67
+ this.#scale = config.scale;
68
+ }
69
+ }
70
+
71
+ tick(dt: number, width: number, height: number): void {
72
+ this.#time += 0.01 * dt * this.#speed;
73
+
74
+ for (const orbiter of this.#orbiters) {
75
+ const center = this.#centers[orbiter.centerIndex];
76
+ const cx = center.x * width;
77
+ const cy = center.y * height;
78
+
79
+ orbiter.angle += orbiter.angularSpeed * dt * this.#speed;
80
+
81
+ const cosAngle = Math.cos(orbiter.angle);
82
+ const sinAngle = Math.sin(orbiter.angle);
83
+ const cosTilt = Math.cos(orbiter.tilt);
84
+
85
+ const localX = cosAngle * orbiter.radiusX * this.#scale;
86
+ const localY = sinAngle * orbiter.radiusY * this.#scale * cosTilt;
87
+
88
+ const rotatedX = localX * Math.cos(orbiter.tilt * 0.3) - localY * Math.sin(orbiter.tilt * 0.3);
89
+ const rotatedY = localX * Math.sin(orbiter.tilt * 0.3) + localY * Math.cos(orbiter.tilt * 0.3);
90
+
91
+ const px = cx + rotatedX;
92
+ const py = cy + rotatedY;
93
+
94
+ const trail = orbiter.trail;
95
+ const maxLen = this.#trailLength;
96
+
97
+ if (trail.length < maxLen) {
98
+ trail.push({x: px, y: py});
99
+ orbiter.trailHead = trail.length - 1;
100
+ } else {
101
+ const next = (orbiter.trailHead + 1) % maxLen;
102
+ trail[next].x = px;
103
+ trail[next].y = py;
104
+ orbiter.trailHead = next;
105
+ }
106
+ }
107
+ }
108
+
109
+ draw(ctx: CanvasRenderingContext2D, width: number, height: number): void {
110
+
111
+ if (this.#showCenters) {
112
+ ctx.globalCompositeOperation = 'lighter';
113
+
114
+ for (const center of this.#centers) {
115
+ const cx = center.x * width;
116
+ const cy = center.y * height;
117
+ const glowRadius = 30 * this.#scale;
118
+
119
+ const gradient = ctx.createRadialGradient(cx, cy, 0, cx, cy, glowRadius);
120
+ gradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');
121
+ gradient.addColorStop(0.4, 'rgba(200, 200, 255, 0.1)');
122
+ gradient.addColorStop(1, 'rgba(200, 200, 255, 0)');
123
+
124
+ ctx.globalAlpha = 1;
125
+ ctx.beginPath();
126
+ ctx.arc(cx, cy, glowRadius, 0, Math.PI * 2);
127
+ ctx.fillStyle = gradient;
128
+ ctx.fill();
129
+ }
130
+
131
+ ctx.globalCompositeOperation = 'source-over';
132
+ }
133
+
134
+ ctx.globalCompositeOperation = 'lighter';
135
+
136
+ for (const orbiter of this.#orbiters) {
137
+ const [cr, cg, cb] = hexToRGB(orbiter.color);
138
+ const trail = orbiter.trail;
139
+ const trailLen = trail.length;
140
+
141
+ if (trailLen > 1) {
142
+ const isFull = trailLen === this.#trailLength;
143
+ const oldest = isFull ? (orbiter.trailHead + 1) % trailLen : 0;
144
+
145
+ for (let ti = 0; ti < trailLen - 1; ti++) {
146
+ const progress = (ti + 1) / trailLen;
147
+ const trailAlpha = progress * 0.5;
148
+ const trailWidth = orbiter.size * progress * this.#scale;
149
+
150
+ if (trailAlpha < 0.01) {
151
+ continue;
152
+ }
153
+
154
+ const idx0 = (oldest + ti) % trailLen;
155
+ const idx1 = (oldest + ti + 1) % trailLen;
156
+
157
+ ctx.globalAlpha = trailAlpha;
158
+ ctx.strokeStyle = `rgb(${cr}, ${cg}, ${cb})`;
159
+ ctx.lineWidth = trailWidth;
160
+ ctx.beginPath();
161
+ ctx.moveTo(trail[idx0].x, trail[idx0].y);
162
+ ctx.lineTo(trail[idx1].x, trail[idx1].y);
163
+ ctx.stroke();
164
+ }
165
+ }
166
+
167
+ if (trailLen > 0) {
168
+ const head = trail[orbiter.trailHead];
169
+ const headSize = orbiter.size * this.#scale;
170
+
171
+ const glow = ctx.createRadialGradient(
172
+ head.x, head.y, 0,
173
+ head.x, head.y, headSize * 3
174
+ );
175
+ glow.addColorStop(0, `rgba(${cr}, ${cg}, ${cb}, 0.9)`);
176
+ glow.addColorStop(0.3, `rgba(${cr}, ${cg}, ${cb}, 0.3)`);
177
+ glow.addColorStop(1, `rgba(${cr}, ${cg}, ${cb}, 0)`);
178
+
179
+ ctx.globalAlpha = 1;
180
+ ctx.beginPath();
181
+ ctx.arc(head.x, head.y, headSize * 3, 0, Math.PI * 2);
182
+ ctx.fillStyle = glow;
183
+ ctx.fill();
184
+
185
+ ctx.beginPath();
186
+ ctx.arc(head.x, head.y, headSize, 0, Math.PI * 2);
187
+ ctx.fillStyle = `rgb(${cr}, ${cg}, ${cb})`;
188
+ ctx.fill();
189
+ }
190
+ }
191
+
192
+ ctx.globalCompositeOperation = 'source-over';
193
+ ctx.globalAlpha = 1;
194
+ }
195
+
196
+ #createOrbiter(centerIndex: number): Orbiter {
197
+ const minRadius = 40;
198
+ const maxRadius = 160;
199
+
200
+ return {
201
+ centerIndex,
202
+ angle: MULBERRY.next() * Math.PI * 2,
203
+ angularSpeed: 0.01 + MULBERRY.next() * 0.03,
204
+ radiusX: minRadius + MULBERRY.next() * (maxRadius - minRadius),
205
+ radiusY: (minRadius + MULBERRY.next() * (maxRadius - minRadius)) * (0.3 + MULBERRY.next() * 0.7),
206
+ tilt: MULBERRY.next() * Math.PI,
207
+ size: 1.5 + MULBERRY.next() * 2.5,
208
+ color: this.#colors[Math.floor(MULBERRY.next() * this.#colors.length)],
209
+ trail: [],
210
+ trailHead: 0
211
+ };
212
+ }
213
+ }
@@ -0,0 +1,27 @@
1
+ export interface OrbitsConfig {
2
+ readonly centers?: number;
3
+ readonly orbitersPerCenter?: number;
4
+ readonly speed?: number;
5
+ readonly colors?: string[];
6
+ readonly trailLength?: number;
7
+ readonly showCenters?: boolean;
8
+ readonly scale?: number;
9
+ }
10
+
11
+ export type OrbitalCenter = {
12
+ x: number;
13
+ y: number;
14
+ };
15
+
16
+ export type Orbiter = {
17
+ centerIndex: number;
18
+ angle: number;
19
+ angularSpeed: number;
20
+ radiusX: number;
21
+ radiusY: number;
22
+ tilt: number;
23
+ size: number;
24
+ color: string;
25
+ trail: { x: number; y: number }[];
26
+ trailHead: number;
27
+ };
@@ -0,0 +1,3 @@
1
+ import { type Mulberry32, mulberry32 } from '@basmilius/utils';
2
+
3
+ export const MULBERRY: Mulberry32 = mulberry32(13);
@@ -0,0 +1,10 @@
1
+ import { Particles } from './layer';
2
+ import type { ParticlesConfig } from './layer';
3
+ import type { Effect } from '../effect';
4
+
5
+ export function createParticles(config?: ParticlesConfig): Effect<ParticlesConfig> {
6
+ return new Particles(config);
7
+ }
8
+
9
+ export type { ParticlesConfig };
10
+ export type { NetworkParticle, ParticleMouseMode } from './types';