@tsparticles/stencil 4.1.3 → 4.2.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.
Files changed (29) hide show
  1. package/README.md +13 -0
  2. package/dist/cjs/{Container-0BqPfTsu.js → Container-BIhHE6mu.js} +659 -1010
  3. package/dist/cjs/{index-Bw7g3biq.js → index-BIoj1BEO.js} +57 -160
  4. package/dist/cjs/{index-B2lLThjb.js → index-BjS63OiI.js} +95 -5
  5. package/dist/cjs/index.cjs.js +1 -1
  6. package/dist/cjs/loader.cjs.js +2 -2
  7. package/dist/cjs/stencil-particles.cjs.entry.js +23 -6
  8. package/dist/cjs/tsparticlesstencil.cjs.js +2 -2
  9. package/dist/collection/components/stencil-particles/stencil-particles.js +83 -4
  10. package/dist/esm/{Container-BxLt611H.js → Container-DZZsfp6i.js} +659 -1010
  11. package/dist/esm/{index-BXzC9NH1.js → index-BH3sNkGS.js} +57 -160
  12. package/dist/esm/{index-DKFk70aj.js → index-PhwiK2_P.js} +95 -6
  13. package/dist/esm/index.js +1 -1
  14. package/dist/esm/loader.js +3 -3
  15. package/dist/esm/stencil-particles.entry.js +23 -6
  16. package/dist/esm/tsparticlesstencil.js +3 -3
  17. package/dist/tsparticlesstencil/index.esm.js +1 -1
  18. package/dist/tsparticlesstencil/p-CIUgBOXY.js +1 -0
  19. package/dist/tsparticlesstencil/p-PhwiK2_P.js +2 -0
  20. package/dist/tsparticlesstencil/p-QSzGOBhI.js +1 -0
  21. package/dist/tsparticlesstencil/p-bd76f15b.entry.js +1 -0
  22. package/dist/tsparticlesstencil/tsparticlesstencil.esm.js +1 -1
  23. package/dist/types/components/stencil-particles/stencil-particles.d.ts +6 -2
  24. package/dist/types/components.d.ts +24 -2
  25. package/package.json +8 -7
  26. package/dist/tsparticlesstencil/p-BhGs05ap.js +0 -1
  27. package/dist/tsparticlesstencil/p-DKFk70aj.js +0 -2
  28. package/dist/tsparticlesstencil/p-LyLjQmWv.js +0 -1
  29. package/dist/tsparticlesstencil/p-cf6e2424.entry.js +0 -1
@@ -1,4 +1,4 @@
1
- import { R as RangeType, c as checkDistance, s as squareExp, a as isNull, b as setRangeValue, h as hMin, d as hMax, l as lMin, e as lMax, f as sMin, g as sMax, j as isString, k as isArray, m as deepExtend, P as PixelMode, O as OutMode, M as MoveDirection, n as isNumber, o as isObject, L as LimitMode, p as executeOnSingleOrMultiple, q as isBoolean, r as originPoint, u as minStrokeWidth, v as defaultZoom, w as itemFromArray, x as defaultOpacity, y as randomColorValue, z as half, A as AlterType, B as lFactor, C as double, D as hPhase, E as rgbMax, F as getRandomInRange, G as identity, H as defaultRgbMin, I as sextuple, J as triple, K as phaseNumerator, N as sNormalizedOffset, Q as minimumSize, S as defaultCompositeValue, T as defaultTransformValue, U as zIndexFactorOffset, V as safeMutationObserver, W as generatedAttribute, X as cloneStyle, Y as safeMatchMedia, Z as getFullScreenStyle, _ as safeDocument, $ as millisecondsToSeconds, a0 as manageListener, a1 as visibilityChangeEvent, a2 as resizeEvent, a3 as Vector3d, a4 as EventType, a5 as defaultAngle, a6 as defaultTransform, a7 as ParticleOutType, a8 as itemFromSingleOrMultiple, a9 as getRandom, aa as defaultRetryCount, ab as tryCountIncrement, ac as getParticleBaseVelocity, ad as randomInRangeValue, ae as OutModeDirection, af as clamp, ag as minZ, ah as getPosition, ai as getParticleDirectionAngle, aj as Vector, ak as getRangeValue, al as doublePI, am as calcExactPositionOrRandomFromSize, an as isInArray, ao as degToRad, ap as spatialHashGridCellSize, aq as minLimit, ar as minCount, as as getLogger, at as minIndex, au as defaultRemoveQuantity, av as defaultDensityFactor, aw as empty, ax as deleteCount, ay as countOffset, az as one, aA as defaultRatio, aB as defaultReduceFactor, aC as animate, aD as defaultFpsLimit, aE as minFpsLimit, aF as cancelAnimation, aG as defaultFps } from './index-BXzC9NH1.js';
1
+ import { R as RangeType, c as checkDistance, s as squareExp, a as isNull, b as setRangeValue, h as hMin, d as hMax, l as lMin, e as lMax, f as sMin, g as sMax, j as isString, k as isArray, m as deepExtend, P as PixelMode, O as OutMode, M as MoveDirection, n as isNumber, o as isObject, L as LimitMode, p as executeOnSingleOrMultiple, q as isBoolean, r as itemFromArray, u as defaultOpacity, v as randomColorValue, A as AlterType, w as lFactor, x as half, y as double, z as hPhase, B as rgbMax, C as getRandomInRange, D as identity, E as defaultRgbMin, F as maxNits, G as sextuple, H as triple, I as phaseNumerator, J as sNormalizedOffset, K as originPoint, N as minimumSize, Q as defaultCompositeValue, S as minStrokeWidth, T as defaultZoom, U as zIndexFactorOffset, V as defaultTransformValue, W as safeMutationObserver, X as generatedAttribute, Y as cloneStyle, Z as safeMatchMedia, _ as getFullScreenStyle, $ as safeDocument, a0 as millisecondsToSeconds, a1 as manageListener, a2 as visibilityChangeEvent, a3 as resizeEvent, a4 as Vector3d, a5 as EventType, a6 as defaultAngle, a7 as defaultTransform, a8 as defaultRetryCount, a9 as tryCountIncrement, aa as getParticleBaseVelocity, ab as randomInRangeValue, ac as getRandom, ad as OutModeDirection, ae as clamp, af as minZ, ag as getPosition, ah as getParticleDirectionAngle, ai as ParticleOutType, aj as Vector, ak as getRangeValue, al as calcExactPositionOrRandomFromSize, am as itemFromSingleOrMultiple, an as isInArray, ao as doublePI, ap as degToRad, aq as spatialHashGridCellSize, ar as minLimit, as as minCount, at as getLogger, au as minIndex, av as defaultRemoveQuantity, aw as defaultDensityFactor, ax as deleteCount, ay as countOffset, az as one, aA as defaultRatio, aB as defaultReduceFactor, aC as animate, aD as defaultFpsLimit, aE as minFpsLimit, aF as cancelAnimation, aG as defaultFps } from './index-BH3sNkGS.js';
2
2
 
3
3
  class BaseRange {
4
4
  position;
@@ -73,93 +73,86 @@ class Rectangle extends BaseRange {
73
73
  }
74
74
  }
75
75
 
76
- class AnimationOptions {
77
- count;
78
- decay;
79
- delay;
80
- enable;
81
- speed;
82
- sync;
83
- constructor() {
84
- this.count = 0;
85
- this.enable = false;
86
- this.speed = 1;
87
- this.decay = 0;
88
- this.delay = 0;
89
- this.sync = false;
90
- }
76
+ class OptionLoader {
91
77
  load(data) {
92
78
  if (isNull(data)) {
93
79
  return;
94
80
  }
95
- if (data.count !== undefined) {
96
- this.count = setRangeValue(data.count);
97
- }
98
- if (data.enable !== undefined) {
99
- this.enable = data.enable;
100
- }
101
- if (data.speed !== undefined) {
102
- this.speed = setRangeValue(data.speed);
103
- }
104
- if (data.decay !== undefined) {
105
- this.decay = setRangeValue(data.decay);
106
- }
107
- if (data.delay !== undefined) {
108
- this.delay = setRangeValue(data.delay);
109
- }
110
- if (data.sync !== undefined) {
111
- this.sync = data.sync;
112
- }
81
+ this.doLoad(data);
82
+ }
83
+ }
84
+ function loadOptions(options, ...sourceOptionsArr) {
85
+ for (const sourceOptions of sourceOptionsArr) {
86
+ options.load(sourceOptions);
87
+ }
88
+ }
89
+
90
+ function loadProperty(obj, key, value) {
91
+ if (value !== undefined) {
92
+ obj[key] = value;
93
+ }
94
+ }
95
+ function loadRangeProperty(obj, key, value) {
96
+ if (value !== undefined) {
97
+ obj[key] = setRangeValue(value);
98
+ }
99
+ }
100
+ function loadLazyProperty(obj, key, value, factory) {
101
+ if (value !== undefined) {
102
+ const objRecord = obj;
103
+ objRecord[key] ??= factory();
104
+ objRecord[key].load(value);
105
+ }
106
+ }
107
+
108
+ class AnimationOptions extends OptionLoader {
109
+ count = 0;
110
+ decay = 0;
111
+ delay = 0;
112
+ enable = false;
113
+ speed = 1;
114
+ sync = false;
115
+ doLoad(data) {
116
+ loadRangeProperty(this, "count", data.count);
117
+ loadProperty(this, "enable", data.enable);
118
+ loadRangeProperty(this, "speed", data.speed);
119
+ loadRangeProperty(this, "decay", data.decay);
120
+ loadRangeProperty(this, "delay", data.delay);
121
+ loadProperty(this, "sync", data.sync);
113
122
  }
114
123
  }
115
124
 
116
125
  class ColorAnimation extends AnimationOptions {
117
126
  max;
118
127
  min;
119
- offset;
128
+ offset = 0;
129
+ sync = true;
120
130
  constructor(min, max) {
121
131
  super();
122
132
  this.min = min;
123
133
  this.max = max;
124
- this.offset = 0;
125
- this.sync = true;
126
134
  }
127
- load(data) {
128
- super.load(data);
129
- if (isNull(data)) {
130
- return;
131
- }
132
- if (data.max !== undefined) {
133
- this.max = data.max;
134
- }
135
- if (data.min !== undefined) {
136
- this.min = data.min;
137
- }
138
- if (data.offset !== undefined) {
139
- this.offset = setRangeValue(data.offset);
140
- }
135
+ doLoad(data) {
136
+ super.doLoad(data);
137
+ loadProperty(this, "max", data.max);
138
+ loadProperty(this, "min", data.min);
139
+ loadRangeProperty(this, "offset", data.offset);
141
140
  }
142
141
  }
143
142
 
144
- class HslAnimation {
143
+ class HslAnimation extends OptionLoader {
145
144
  h = new ColorAnimation(hMin, hMax);
146
145
  l = new ColorAnimation(lMin, lMax);
147
146
  s = new ColorAnimation(sMin, sMax);
148
- load(data) {
149
- if (isNull(data)) {
150
- return;
151
- }
147
+ doLoad(data) {
152
148
  this.h.load(data.h);
153
149
  this.s.load(data.s);
154
150
  this.l.load(data.l);
155
151
  }
156
152
  }
157
153
 
158
- class OptionsColor {
159
- value;
160
- constructor() {
161
- this.value = "";
162
- }
154
+ class OptionsColor extends OptionLoader {
155
+ value = "";
163
156
  static create(source, data) {
164
157
  const color = new OptionsColor();
165
158
  color.load(source);
@@ -173,10 +166,7 @@ class OptionsColor {
173
166
  }
174
167
  return color;
175
168
  }
176
- load(data) {
177
- if (isNull(data)) {
178
- return;
179
- }
169
+ doLoad(data) {
180
170
  if (!isNull(data.value)) {
181
171
  this.value = data.value;
182
172
  }
@@ -184,11 +174,7 @@ class OptionsColor {
184
174
  }
185
175
 
186
176
  class AnimatableColor extends OptionsColor {
187
- animation;
188
- constructor() {
189
- super();
190
- this.animation = new HslAnimation();
191
- }
177
+ animation = new HslAnimation();
192
178
  static create(source, data) {
193
179
  const color = new AnimatableColor();
194
180
  color.load(source);
@@ -202,11 +188,8 @@ class AnimatableColor extends OptionsColor {
202
188
  }
203
189
  return color;
204
190
  }
205
- load(data) {
206
- super.load(data);
207
- if (isNull(data)) {
208
- return;
209
- }
191
+ doLoad(data) {
192
+ super.doLoad(data);
210
193
  const colorAnimation = data.animation;
211
194
  if (colorAnimation !== undefined) {
212
195
  if (colorAnimation.enable === undefined) {
@@ -219,100 +202,53 @@ class AnimatableColor extends OptionsColor {
219
202
  }
220
203
  }
221
204
 
222
- class Background {
205
+ class Background extends OptionLoader {
223
206
  color;
224
- image;
225
- opacity;
226
- position;
227
- repeat;
228
- size;
207
+ image = "";
208
+ opacity = 1;
209
+ position = "";
210
+ repeat = "";
211
+ size = "";
229
212
  constructor() {
213
+ super();
230
214
  this.color = new OptionsColor();
231
215
  this.color.value = "";
232
- this.image = "";
233
- this.position = "";
234
- this.repeat = "";
235
- this.size = "";
236
- this.opacity = 1;
237
216
  }
238
- load(data) {
239
- if (isNull(data)) {
240
- return;
241
- }
217
+ doLoad(data) {
242
218
  if (data.color !== undefined) {
243
219
  this.color = OptionsColor.create(this.color, data.color);
244
220
  }
245
- if (data.image !== undefined) {
246
- this.image = data.image;
247
- }
248
- if (data.position !== undefined) {
249
- this.position = data.position;
250
- }
251
- if (data.repeat !== undefined) {
252
- this.repeat = data.repeat;
253
- }
254
- if (data.size !== undefined) {
255
- this.size = data.size;
256
- }
257
- if (data.opacity !== undefined) {
258
- this.opacity = data.opacity;
259
- }
221
+ loadProperty(this, "image", data.image);
222
+ loadProperty(this, "position", data.position);
223
+ loadProperty(this, "repeat", data.repeat);
224
+ loadProperty(this, "size", data.size);
225
+ loadProperty(this, "opacity", data.opacity);
260
226
  }
261
227
  }
262
228
 
263
- class FullScreen {
264
- enable;
265
- zIndex;
266
- constructor() {
267
- this.enable = true;
268
- this.zIndex = 0;
269
- }
270
- load(data) {
271
- if (isNull(data)) {
272
- return;
273
- }
274
- if (data.enable !== undefined) {
275
- this.enable = data.enable;
276
- }
277
- if (data.zIndex !== undefined) {
278
- this.zIndex = data.zIndex;
279
- }
229
+ class FullScreen extends OptionLoader {
230
+ enable = true;
231
+ zIndex = 0;
232
+ doLoad(data) {
233
+ loadProperty(this, "enable", data.enable);
234
+ loadProperty(this, "zIndex", data.zIndex);
280
235
  }
281
236
  }
282
237
 
283
- class ResizeEvent {
284
- delay;
285
- enable;
286
- constructor() {
287
- this.delay = 0.5;
288
- this.enable = true;
289
- }
290
- load(data) {
291
- if (isNull(data)) {
292
- return;
293
- }
294
- if (data.delay !== undefined) {
295
- this.delay = data.delay;
296
- }
297
- if (data.enable !== undefined) {
298
- this.enable = data.enable;
299
- }
238
+ class ResizeEvent extends OptionLoader {
239
+ delay = 0.5;
240
+ enable = true;
241
+ doLoad(data) {
242
+ loadProperty(this, "delay", data.delay);
243
+ loadProperty(this, "enable", data.enable);
300
244
  }
301
245
  }
302
246
 
303
- class Effect {
304
- close;
305
- options;
306
- type;
307
- constructor() {
308
- this.close = true;
309
- this.options = {};
310
- this.type = [];
311
- }
312
- load(data) {
313
- if (isNull(data)) {
314
- return;
315
- }
247
+ class Effect extends OptionLoader {
248
+ close = true;
249
+ options = {};
250
+ type = [];
251
+ doLoad(data) {
316
252
  const options = data.options;
317
253
  if (options !== undefined) {
318
254
  for (const effect in options) {
@@ -322,157 +258,78 @@ class Effect {
322
258
  }
323
259
  }
324
260
  }
325
- if (data.close !== undefined) {
326
- this.close = data.close;
327
- }
328
- if (data.type !== undefined) {
329
- this.type = data.type;
330
- }
261
+ loadProperty(this, "close", data.close);
262
+ loadProperty(this, "type", data.type);
331
263
  }
332
264
  }
333
265
 
334
- class Fill {
266
+ class Fill extends OptionLoader {
335
267
  color;
336
- enable;
337
- opacity;
338
- constructor() {
339
- this.enable = true;
340
- this.opacity = 1;
341
- }
342
- load(data) {
343
- if (isNull(data)) {
344
- return;
345
- }
268
+ enable = true;
269
+ opacity = 1;
270
+ doLoad(data) {
346
271
  if (data.color !== undefined) {
347
272
  this.color = AnimatableColor.create(this.color, data.color);
348
273
  }
349
- if (data.enable !== undefined) {
350
- this.enable = data.enable;
351
- }
352
- if (data.opacity !== undefined) {
353
- this.opacity = setRangeValue(data.opacity);
354
- }
274
+ loadProperty(this, "enable", data.enable);
275
+ loadRangeProperty(this, "opacity", data.opacity);
355
276
  }
356
277
  }
357
278
 
358
- class MoveAngle {
359
- offset;
360
- value;
361
- constructor() {
362
- this.offset = 0;
363
- this.value = 90;
364
- }
365
- load(data) {
366
- if (isNull(data)) {
367
- return;
368
- }
369
- if (data.offset !== undefined) {
370
- this.offset = setRangeValue(data.offset);
371
- }
372
- if (data.value !== undefined) {
373
- this.value = setRangeValue(data.value);
374
- }
279
+ class MoveAngle extends OptionLoader {
280
+ offset = 0;
281
+ value = 90;
282
+ doLoad(data) {
283
+ loadRangeProperty(this, "offset", data.offset);
284
+ loadRangeProperty(this, "value", data.value);
375
285
  }
376
286
  }
377
287
 
378
- class MoveCenter {
379
- mode;
380
- radius;
381
- x;
382
- y;
383
- constructor() {
384
- this.x = 50;
385
- this.y = 50;
386
- this.mode = PixelMode.percent;
387
- this.radius = 0;
388
- }
389
- load(data) {
390
- if (isNull(data)) {
391
- return;
392
- }
393
- if (data.x !== undefined) {
394
- this.x = data.x;
395
- }
396
- if (data.y !== undefined) {
397
- this.y = data.y;
398
- }
399
- if (data.mode !== undefined) {
400
- this.mode = data.mode;
401
- }
402
- if (data.radius !== undefined) {
403
- this.radius = data.radius;
404
- }
288
+ class MoveCenter extends OptionLoader {
289
+ mode = PixelMode.percent;
290
+ radius = 0;
291
+ x = 50;
292
+ y = 50;
293
+ doLoad(data) {
294
+ loadProperty(this, "x", data.x);
295
+ loadProperty(this, "y", data.y);
296
+ loadProperty(this, "mode", data.mode);
297
+ loadProperty(this, "radius", data.radius);
405
298
  }
406
299
  }
407
300
 
408
- class MoveGravity {
409
- acceleration;
410
- enable;
411
- inverse;
412
- maxSpeed;
413
- constructor() {
414
- this.acceleration = 9.81;
415
- this.enable = false;
416
- this.inverse = false;
417
- this.maxSpeed = 50;
418
- }
419
- load(data) {
420
- if (isNull(data)) {
421
- return;
422
- }
423
- if (data.acceleration !== undefined) {
424
- this.acceleration = setRangeValue(data.acceleration);
425
- }
426
- if (data.enable !== undefined) {
427
- this.enable = data.enable;
428
- }
429
- if (data.inverse !== undefined) {
430
- this.inverse = data.inverse;
431
- }
432
- if (data.maxSpeed !== undefined) {
433
- this.maxSpeed = setRangeValue(data.maxSpeed);
434
- }
301
+ class MoveGravity extends OptionLoader {
302
+ acceleration = 9.81;
303
+ enable = false;
304
+ inverse = false;
305
+ maxSpeed = 50;
306
+ doLoad(data) {
307
+ loadRangeProperty(this, "acceleration", data.acceleration);
308
+ loadProperty(this, "enable", data.enable);
309
+ loadProperty(this, "inverse", data.inverse);
310
+ loadRangeProperty(this, "maxSpeed", data.maxSpeed);
435
311
  }
436
312
  }
437
313
 
438
- class ValueWithRandom {
439
- value;
440
- constructor() {
441
- this.value = 0;
442
- }
443
- load(data) {
444
- if (isNull(data)) {
445
- return;
446
- }
314
+ class ValueWithRandom extends OptionLoader {
315
+ value = 0;
316
+ doLoad(data) {
447
317
  if (!isNull(data.value)) {
448
318
  this.value = setRangeValue(data.value);
449
319
  }
450
320
  }
451
321
  }
452
322
 
453
- class MovePath {
454
- clamp;
455
- delay;
456
- enable;
323
+ class MovePath extends OptionLoader {
324
+ clamp = true;
325
+ delay = new ValueWithRandom();
326
+ enable = false;
457
327
  generator;
458
- options;
459
- constructor() {
460
- this.clamp = true;
461
- this.delay = new ValueWithRandom();
462
- this.enable = false;
463
- this.options = {};
464
- }
465
- load(data) {
466
- if (isNull(data)) {
467
- return;
468
- }
469
- if (data.clamp !== undefined) {
470
- this.clamp = data.clamp;
471
- }
328
+ options = {};
329
+ doLoad(data) {
330
+ loadProperty(this, "clamp", data.clamp);
472
331
  this.delay.load(data.delay);
473
- if (data.enable !== undefined) {
474
- this.enable = data.enable;
475
- }
332
+ loadProperty(this, "enable", data.enable);
476
333
  this.generator = data.generator;
477
334
  if (data.options) {
478
335
  this.options = deepExtend(this.options, data.options);
@@ -480,19 +337,13 @@ class MovePath {
480
337
  }
481
338
  }
482
339
 
483
- class OutModes {
340
+ class OutModes extends OptionLoader {
484
341
  bottom;
485
- default;
342
+ default = OutMode.out;
486
343
  left;
487
344
  right;
488
345
  top;
489
- constructor() {
490
- this.default = OutMode.out;
491
- }
492
- load(data) {
493
- if (isNull(data)) {
494
- return;
495
- }
346
+ doLoad(data) {
496
347
  if (data.default !== undefined) {
497
348
  this.default = data.default;
498
349
  }
@@ -503,79 +354,42 @@ class OutModes {
503
354
  }
504
355
  }
505
356
 
506
- class Spin {
507
- acceleration;
508
- enable;
357
+ class Spin extends OptionLoader {
358
+ acceleration = 0;
359
+ enable = false;
509
360
  position;
510
- constructor() {
511
- this.acceleration = 0;
512
- this.enable = false;
513
- }
514
- load(data) {
515
- if (isNull(data)) {
516
- return;
517
- }
518
- if (data.acceleration !== undefined) {
519
- this.acceleration = setRangeValue(data.acceleration);
520
- }
521
- if (data.enable !== undefined) {
522
- this.enable = data.enable;
523
- }
361
+ doLoad(data) {
362
+ loadRangeProperty(this, "acceleration", data.acceleration);
363
+ loadProperty(this, "enable", data.enable);
524
364
  if (data.position) {
525
365
  this.position = deepExtend({}, data.position);
526
366
  }
527
367
  }
528
368
  }
529
369
 
530
- class Move {
531
- angle;
532
- center;
533
- decay;
534
- direction;
535
- distance;
536
- drift;
537
- enable;
538
- gravity;
539
- outModes;
540
- path;
541
- random;
542
- size;
543
- speed;
544
- spin;
545
- straight;
546
- vibrate;
547
- warp;
548
- constructor() {
549
- this.angle = new MoveAngle();
550
- this.center = new MoveCenter();
551
- this.decay = 0;
552
- this.distance = {};
553
- this.direction = MoveDirection.none;
554
- this.drift = 0;
555
- this.enable = false;
556
- this.gravity = new MoveGravity();
557
- this.path = new MovePath();
558
- this.outModes = new OutModes();
559
- this.random = false;
560
- this.size = false;
561
- this.speed = 2;
562
- this.spin = new Spin();
563
- this.straight = false;
564
- this.vibrate = false;
565
- this.warp = false;
566
- }
567
- load(data) {
568
- if (isNull(data)) {
569
- return;
570
- }
370
+ class Move extends OptionLoader {
371
+ angle = new MoveAngle();
372
+ center = new MoveCenter();
373
+ decay = 0;
374
+ direction = MoveDirection.none;
375
+ distance = {};
376
+ drift = 0;
377
+ enable = false;
378
+ gravity = new MoveGravity();
379
+ outModes = new OutModes();
380
+ path = new MovePath();
381
+ random = false;
382
+ size = false;
383
+ speed = 2;
384
+ spin = new Spin();
385
+ straight = false;
386
+ vibrate = false;
387
+ warp = false;
388
+ doLoad(data) {
571
389
  this.angle.load(isNumber(data.angle) ? { value: data.angle } : data.angle);
572
390
  this.center.load(data.center);
573
- if (data.decay !== undefined) {
574
- this.decay = setRangeValue(data.decay);
575
- }
576
- if (data.direction !== undefined) {
577
- this.direction = data.direction;
578
- }
391
+ loadRangeProperty(this, "decay", data.decay);
392
+ loadProperty(this, "direction", data.direction);
579
393
  if (data.distance !== undefined) {
580
394
  this.distance = isNumber(data.distance)
581
395
  ? {
@@ -584,12 +398,8 @@ class Move {
584
398
  }
585
399
  : { ...data.distance };
586
400
  }
587
- if (data.drift !== undefined) {
588
- this.drift = setRangeValue(data.drift);
589
- }
590
- if (data.enable !== undefined) {
591
- this.enable = data.enable;
592
- }
401
+ loadRangeProperty(this, "drift", data.drift);
402
+ loadProperty(this, "enable", data.enable);
593
403
  this.gravity.load(data.gravity);
594
404
  const outModes = data.outModes;
595
405
  if (outModes !== undefined) {
@@ -603,177 +413,91 @@ class Move {
603
413
  }
604
414
  }
605
415
  this.path.load(data.path);
606
- if (data.random !== undefined) {
607
- this.random = data.random;
608
- }
609
- if (data.size !== undefined) {
610
- this.size = data.size;
611
- }
612
- if (data.speed !== undefined) {
613
- this.speed = setRangeValue(data.speed);
614
- }
416
+ loadProperty(this, "random", data.random);
417
+ loadProperty(this, "size", data.size);
418
+ loadRangeProperty(this, "speed", data.speed);
615
419
  this.spin.load(data.spin);
616
- if (data.straight !== undefined) {
617
- this.straight = data.straight;
618
- }
619
- if (data.vibrate !== undefined) {
620
- this.vibrate = data.vibrate;
621
- }
622
- if (data.warp !== undefined) {
623
- this.warp = data.warp;
624
- }
420
+ loadProperty(this, "straight", data.straight);
421
+ loadProperty(this, "vibrate", data.vibrate);
422
+ loadProperty(this, "warp", data.warp);
625
423
  }
626
424
  }
627
425
 
628
- class Stroke {
426
+ class Stroke extends OptionLoader {
629
427
  color;
630
428
  opacity;
631
- width;
632
- constructor() {
633
- this.width = 0;
634
- }
635
- load(data) {
636
- if (isNull(data)) {
637
- return;
638
- }
429
+ width = 0;
430
+ doLoad(data) {
639
431
  if (data.color !== undefined) {
640
432
  this.color = AnimatableColor.create(this.color, data.color);
641
433
  }
642
- if (data.width !== undefined) {
643
- this.width = setRangeValue(data.width);
644
- }
645
- if (data.opacity !== undefined) {
646
- this.opacity = setRangeValue(data.opacity);
647
- }
434
+ loadRangeProperty(this, "width", data.width);
435
+ loadRangeProperty(this, "opacity", data.opacity);
648
436
  }
649
437
  }
650
438
 
651
- class Paint {
439
+ class Paint extends OptionLoader {
652
440
  color;
653
441
  fill;
654
442
  stroke;
655
- load(data) {
656
- if (isNull(data)) {
657
- return;
658
- }
443
+ doLoad(data) {
659
444
  if (data.color !== undefined) {
660
445
  this.color = AnimatableColor.create(this.color, data.color);
661
446
  }
662
- if (data.fill !== undefined) {
663
- this.fill ??= new Fill();
664
- this.fill.load(data.fill);
665
- }
666
- if (data.stroke !== undefined) {
667
- this.stroke ??= new Stroke();
668
- this.stroke.load(data.stroke);
669
- }
447
+ loadLazyProperty(this, "fill", data.fill, () => new Fill());
448
+ loadLazyProperty(this, "stroke", data.stroke, () => new Stroke());
670
449
  }
671
450
  }
672
451
 
673
452
  class ParticlesBounceFactor extends ValueWithRandom {
674
- constructor() {
675
- super();
676
- this.value = 1;
677
- }
453
+ value = 1;
678
454
  }
679
455
 
680
- class ParticlesBounce {
681
- horizontal;
682
- vertical;
683
- constructor() {
684
- this.horizontal = new ParticlesBounceFactor();
685
- this.vertical = new ParticlesBounceFactor();
686
- }
687
- load(data) {
688
- if (isNull(data)) {
689
- return;
690
- }
456
+ class ParticlesBounce extends OptionLoader {
457
+ horizontal = new ParticlesBounceFactor();
458
+ vertical = new ParticlesBounceFactor();
459
+ doLoad(data) {
691
460
  this.horizontal.load(data.horizontal);
692
461
  this.vertical.load(data.vertical);
693
462
  }
694
463
  }
695
464
 
696
- class ParticlesDensity {
697
- enable;
698
- height;
699
- width;
700
- constructor() {
701
- this.enable = false;
702
- this.width = 1920;
703
- this.height = 1080;
704
- }
705
- load(data) {
706
- if (isNull(data)) {
707
- return;
708
- }
709
- if (data.enable !== undefined) {
710
- this.enable = data.enable;
711
- }
712
- const width = data.width;
713
- if (width !== undefined) {
714
- this.width = width;
715
- }
716
- const height = data.height;
717
- if (height !== undefined) {
718
- this.height = height;
719
- }
465
+ class ParticlesDensity extends OptionLoader {
466
+ enable = false;
467
+ height = 1080;
468
+ width = 1920;
469
+ doLoad(data) {
470
+ loadProperty(this, "enable", data.enable);
471
+ loadProperty(this, "width", data.width);
472
+ loadProperty(this, "height", data.height);
720
473
  }
721
474
  }
722
475
 
723
- class ParticlesNumberLimit {
724
- mode;
725
- value;
726
- constructor() {
727
- this.mode = LimitMode.delete;
728
- this.value = 0;
729
- }
730
- load(data) {
731
- if (isNull(data)) {
732
- return;
733
- }
734
- if (data.mode !== undefined) {
735
- this.mode = data.mode;
736
- }
737
- if (data.value !== undefined) {
738
- this.value = data.value;
739
- }
476
+ class ParticlesNumberLimit extends OptionLoader {
477
+ mode = LimitMode.delete;
478
+ value = 0;
479
+ doLoad(data) {
480
+ loadProperty(this, "mode", data.mode);
481
+ loadProperty(this, "value", data.value);
740
482
  }
741
483
  }
742
484
 
743
- class ParticlesNumber {
744
- density;
745
- limit;
746
- value;
747
- constructor() {
748
- this.density = new ParticlesDensity();
749
- this.limit = new ParticlesNumberLimit();
750
- this.value = 0;
751
- }
752
- load(data) {
753
- if (isNull(data)) {
754
- return;
755
- }
485
+ class ParticlesNumber extends OptionLoader {
486
+ density = new ParticlesDensity();
487
+ limit = new ParticlesNumberLimit();
488
+ value = 0;
489
+ doLoad(data) {
756
490
  this.density.load(data.density);
757
491
  this.limit.load(data.limit);
758
- if (data.value !== undefined) {
759
- this.value = data.value;
760
- }
492
+ loadProperty(this, "value", data.value);
761
493
  }
762
494
  }
763
495
 
764
- class Shape {
765
- close;
766
- options;
767
- type;
768
- constructor() {
769
- this.close = true;
770
- this.options = {};
771
- this.type = "circle";
772
- }
773
- load(data) {
774
- if (isNull(data)) {
775
- return;
776
- }
496
+ class Shape extends OptionLoader {
497
+ close = true;
498
+ options = {};
499
+ type = "circle";
500
+ doLoad(data) {
777
501
  const options = data.options;
778
502
  if (options !== undefined) {
779
503
  for (const shape in options) {
@@ -783,76 +507,47 @@ class Shape {
783
507
  }
784
508
  }
785
509
  }
786
- if (data.close !== undefined) {
787
- this.close = data.close;
788
- }
789
- if (data.type !== undefined) {
790
- this.type = data.type;
791
- }
510
+ loadProperty(this, "close", data.close);
511
+ loadProperty(this, "type", data.type);
792
512
  }
793
513
  }
794
514
 
795
515
  class ZIndex extends ValueWithRandom {
796
- opacityRate;
797
- sizeRate;
798
- velocityRate;
799
- constructor() {
800
- super();
801
- this.opacityRate = 1;
802
- this.sizeRate = 1;
803
- this.velocityRate = 1;
804
- }
805
- load(data) {
806
- super.load(data);
807
- if (isNull(data)) {
808
- return;
809
- }
810
- if (data.opacityRate !== undefined) {
811
- this.opacityRate = data.opacityRate;
812
- }
813
- if (data.sizeRate !== undefined) {
814
- this.sizeRate = data.sizeRate;
815
- }
816
- if (data.velocityRate !== undefined) {
817
- this.velocityRate = data.velocityRate;
818
- }
516
+ opacityRate = 1;
517
+ sizeRate = 1;
518
+ velocityRate = 1;
519
+ doLoad(data) {
520
+ super.doLoad(data);
521
+ loadProperty(this, "opacityRate", data.opacityRate);
522
+ loadProperty(this, "sizeRate", data.sizeRate);
523
+ loadProperty(this, "velocityRate", data.velocityRate);
819
524
  }
820
525
  }
821
526
 
822
- class ParticlesOptions {
823
- bounce;
824
- effect;
825
- groups;
826
- move;
827
- number;
527
+ class ParticlesOptions extends OptionLoader {
528
+ bounce = new ParticlesBounce();
529
+ effect = new Effect();
530
+ groups = {};
531
+ move = new Move();
532
+ number = new ParticlesNumber();
828
533
  paint;
829
534
  palette;
830
- reduceDuplicates;
831
- shape;
832
- zIndex;
535
+ reduceDuplicates = false;
536
+ shape = new Shape();
537
+ zIndex = new ZIndex();
833
538
  #container;
834
539
  #pluginManager;
835
540
  constructor(pluginManager, container) {
541
+ super();
836
542
  this.#pluginManager = pluginManager;
837
543
  this.#container = container;
838
- this.bounce = new ParticlesBounce();
839
- this.effect = new Effect();
840
- this.groups = {};
841
- this.move = new Move();
842
- this.number = new ParticlesNumber();
843
544
  this.paint = new Paint();
844
545
  this.paint.color = new AnimatableColor();
845
546
  this.paint.color.value = "#fff";
846
547
  this.paint.fill = new Fill();
847
548
  this.paint.fill.enable = true;
848
- this.reduceDuplicates = false;
849
- this.shape = new Shape();
850
- this.zIndex = new ZIndex();
851
549
  }
852
- load(data) {
853
- if (isNull(data)) {
854
- return;
855
- }
550
+ doLoad(data) {
856
551
  if (data.palette) {
857
552
  this.palette = data.palette;
858
553
  this.#importPalette(this.palette);
@@ -910,7 +605,7 @@ class ParticlesOptions {
910
605
  }
911
606
  }
912
607
  }
913
- #importPalette = (palette) => {
608
+ #importPalette(palette) {
914
609
  const paletteData = this.#pluginManager.getPalette(palette);
915
610
  if (!paletteData) {
916
611
  return;
@@ -954,69 +649,49 @@ class ParticlesOptions {
954
649
  mode: paletteData.blendMode,
955
650
  },
956
651
  });
957
- };
958
- }
959
-
960
- function loadOptions(options, ...sourceOptionsArr) {
961
- for (const sourceOptions of sourceOptionsArr) {
962
- options.load(sourceOptions);
963
652
  }
964
653
  }
654
+
965
655
  function loadParticlesOptions(pluginManager, container, ...sourceOptionsArr) {
966
656
  const options = new ParticlesOptions(pluginManager, container);
967
657
  loadOptions(options, ...sourceOptionsArr);
968
658
  return options;
969
659
  }
970
660
 
971
- class Options {
972
- autoPlay;
661
+ class Options extends OptionLoader {
662
+ autoPlay = true;
973
663
  background;
974
- clear;
975
- defaultThemes;
976
- delay;
977
- detectRetina;
978
- duration;
979
- fpsLimit;
664
+ clear = true;
665
+ defaultThemes = {};
666
+ delay = 0;
667
+ detectRetina = true;
668
+ duration = 0;
669
+ fpsLimit = 120;
980
670
  fullScreen;
981
- hdr;
671
+ hdr = true;
982
672
  key;
983
673
  name;
984
674
  palette;
985
675
  particles;
986
- pauseOnBlur;
987
- pauseOnOutsideViewport;
676
+ pauseOnBlur = true;
677
+ pauseOnOutsideViewport = true;
988
678
  preset;
989
679
  resize;
990
- smooth;
991
- style;
992
- zLayers;
680
+ smooth = false;
681
+ style = {};
682
+ zLayers = 100;
993
683
  #container;
994
684
  #pluginManager;
995
685
  constructor(pluginManager, container) {
686
+ super();
996
687
  this.#pluginManager = pluginManager;
997
688
  this.#container = container;
998
- this.autoPlay = true;
999
689
  this.background = new Background();
1000
- this.clear = true;
1001
- this.defaultThemes = {};
1002
- this.delay = 0;
1003
690
  this.fullScreen = new FullScreen();
1004
- this.detectRetina = true;
1005
- this.duration = 0;
1006
- this.fpsLimit = 120;
1007
- this.hdr = true;
1008
691
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1009
- this.pauseOnBlur = true;
1010
- this.pauseOnOutsideViewport = true;
1011
692
  this.resize = new ResizeEvent();
1012
- this.smooth = false;
1013
- this.style = {};
1014
- this.zLayers = 100;
1015
693
  }
1016
- load(data) {
1017
- if (isNull(data)) {
1018
- return;
1019
- }
694
+ doLoad(data) {
1020
695
  if (data.preset !== undefined) {
1021
696
  this.preset = data.preset;
1022
697
  executeOnSingleOrMultiple(this.preset, preset => {
@@ -1027,44 +702,18 @@ class Options {
1027
702
  this.palette = data.palette;
1028
703
  this.#importPalette(this.palette);
1029
704
  }
1030
- if (data.autoPlay !== undefined) {
1031
- this.autoPlay = data.autoPlay;
1032
- }
1033
- if (data.clear !== undefined) {
1034
- this.clear = data.clear;
1035
- }
1036
- if (data.key !== undefined) {
1037
- this.key = data.key;
1038
- }
1039
- if (data.name !== undefined) {
1040
- this.name = data.name;
1041
- }
1042
- if (data.delay !== undefined) {
1043
- this.delay = setRangeValue(data.delay);
1044
- }
1045
- const detectRetina = data.detectRetina;
1046
- if (detectRetina !== undefined) {
1047
- this.detectRetina = detectRetina;
1048
- }
1049
- if (data.duration !== undefined) {
1050
- this.duration = setRangeValue(data.duration);
1051
- }
1052
- const fpsLimit = data.fpsLimit;
1053
- if (fpsLimit !== undefined) {
1054
- this.fpsLimit = fpsLimit;
1055
- }
1056
- if (data.hdr !== undefined) {
1057
- this.hdr = data.hdr;
1058
- }
1059
- if (data.pauseOnBlur !== undefined) {
1060
- this.pauseOnBlur = data.pauseOnBlur;
1061
- }
1062
- if (data.pauseOnOutsideViewport !== undefined) {
1063
- this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
1064
- }
1065
- if (data.zLayers !== undefined) {
1066
- this.zLayers = data.zLayers;
1067
- }
705
+ loadProperty(this, "autoPlay", data.autoPlay);
706
+ loadProperty(this, "clear", data.clear);
707
+ loadProperty(this, "key", data.key);
708
+ loadProperty(this, "name", data.name);
709
+ loadRangeProperty(this, "delay", data.delay);
710
+ loadProperty(this, "detectRetina", data.detectRetina);
711
+ loadRangeProperty(this, "duration", data.duration);
712
+ loadProperty(this, "fpsLimit", data.fpsLimit);
713
+ loadProperty(this, "hdr", data.hdr);
714
+ loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
715
+ loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
716
+ loadProperty(this, "zLayers", data.zLayers);
1068
717
  this.background.load(data.background);
1069
718
  const fullScreen = data.fullScreen;
1070
719
  if (isBoolean(fullScreen)) {
@@ -1076,14 +725,12 @@ class Options {
1076
725
  this.particles.load(data.particles);
1077
726
  this.resize.load(data.resize);
1078
727
  this.style = deepExtend(this.style, data.style);
1079
- if (data.smooth !== undefined) {
1080
- this.smooth = data.smooth;
1081
- }
728
+ loadProperty(this, "smooth", data.smooth);
1082
729
  this.#pluginManager.plugins.forEach(plugin => {
1083
730
  plugin.loadOptions(this.#container, this, data);
1084
731
  });
1085
732
  }
1086
- #importPalette = palette => {
733
+ #importPalette(palette) {
1087
734
  const paletteData = this.#pluginManager.getPalette(palette);
1088
735
  if (!paletteData) {
1089
736
  return;
@@ -1100,143 +747,19 @@ class Options {
1100
747
  palette,
1101
748
  },
1102
749
  });
1103
- };
1104
- #importPreset = preset => {
1105
- this.load(this.#pluginManager.getPreset(preset));
1106
- };
1107
- }
1108
-
1109
- function paintBase(context, dimension, baseColor) {
1110
- context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
1111
- context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
1112
- }
1113
- function paintImage(context, dimension, image, opacity) {
1114
- if (!image) {
1115
- return;
1116
- }
1117
- const prevAlpha = context.globalAlpha;
1118
- context.globalAlpha = opacity;
1119
- context.drawImage(image, originPoint.x, originPoint.y, dimension.width, dimension.height);
1120
- context.globalAlpha = prevAlpha;
1121
- }
1122
- function clear(context, dimension) {
1123
- context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
1124
- }
1125
- function drawParticle(data) {
1126
- const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
1127
- x: pos.x,
1128
- y: pos.y,
1129
- };
1130
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
1131
- if (colorStyles.fill) {
1132
- context.fillStyle = colorStyles.fill;
1133
- }
1134
- const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
1135
- context.lineWidth = strokeWidth;
1136
- if (colorStyles.stroke) {
1137
- context.strokeStyle = colorStyles.stroke;
1138
- }
1139
- const drawData = {
1140
- context,
1141
- particle,
1142
- radius,
1143
- drawRadius: radius * drawScale,
1144
- opacity,
1145
- delta,
1146
- pixelRatio: container.retina.pixelRatio,
1147
- fill: fillEnabled,
1148
- stroke: strokeWidth > minStrokeWidth,
1149
- transformData,
1150
- position: { ...pos },
1151
- drawPosition,
1152
- drawScale,
1153
- };
1154
- for (const plugin of container.plugins) {
1155
- plugin.drawParticleTransform?.(drawData);
1156
- }
1157
- const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
1158
- drawBeforeEffect(effect, drawData);
1159
- drawShapeBeforeDraw(shape, drawData);
1160
- drawShape(shape, drawData);
1161
- drawShapeAfterDraw(shape, drawData);
1162
- drawAfterEffect(effect, drawData);
1163
- context.resetTransform();
1164
- }
1165
- function drawAfterEffect(drawer, data) {
1166
- if (!drawer?.drawAfter) {
1167
- return;
1168
- }
1169
- const { particle } = data;
1170
- if (!particle.effect) {
1171
- return;
1172
- }
1173
- drawer.drawAfter(data);
1174
- }
1175
- function drawBeforeEffect(drawer, data) {
1176
- if (!drawer?.drawBefore) {
1177
- return;
1178
- }
1179
- const { particle } = data;
1180
- if (!particle.effect) {
1181
- return;
1182
- }
1183
- drawer.drawBefore(data);
1184
- }
1185
- function drawShape(drawer, data) {
1186
- if (!drawer) {
1187
- return;
1188
- }
1189
- const { context, fill, particle, stroke } = data;
1190
- if (!particle.shape) {
1191
- return;
1192
- }
1193
- context.beginPath();
1194
- drawer.draw(data);
1195
- if (particle.shapeClose) {
1196
- context.closePath();
1197
- }
1198
- if (fill) {
1199
- context.fill();
1200
- }
1201
- if (stroke) {
1202
- context.stroke();
1203
- }
1204
- }
1205
- function drawShapeAfterDraw(drawer, data) {
1206
- if (!drawer?.afterDraw) {
1207
- return;
1208
- }
1209
- const { particle } = data;
1210
- if (!particle.shape) {
1211
- return;
1212
- }
1213
- drawer.afterDraw(data);
1214
- }
1215
- function drawShapeBeforeDraw(drawer, data) {
1216
- if (!drawer?.beforeDraw) {
1217
- return;
1218
750
  }
1219
- const { particle } = data;
1220
- if (!particle.shape) {
1221
- return;
1222
- }
1223
- drawer.beforeDraw(data);
1224
- }
1225
- function drawParticlePlugin(context, plugin, particle, delta) {
1226
- if (!plugin.drawParticle) {
1227
- return;
751
+ #importPreset(preset) {
752
+ this.load(this.#pluginManager.getPreset(preset));
1228
753
  }
1229
- plugin.drawParticle(context, particle, delta);
1230
754
  }
1231
755
 
1232
- const styleCache = new Map(), maxCacheSize = 1000, firstIndex = 0, rgbFixedPrecision = 2, hslFixedPrecision = 2;
756
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
1233
757
  function getCachedStyle(key, generator) {
1234
758
  let cached = styleCache.get(key);
1235
759
  if (!cached) {
1236
760
  cached = generator();
1237
- if (styleCache.size >= maxCacheSize) {
1238
- const keysToDelete = [...styleCache.keys()].slice(firstIndex, maxCacheSize * half);
1239
- keysToDelete.forEach(k => styleCache.delete(k));
761
+ if (styleCache.size > maxStyleCacheSize) {
762
+ styleCache.clear();
1240
763
  }
1241
764
  styleCache.set(key, cached);
1242
765
  }
@@ -1339,34 +862,35 @@ function rgbToHsl(color) {
1339
862
  function stringToRgb(pluginManager, input) {
1340
863
  return stringToRgba(pluginManager, input);
1341
864
  }
865
+ function hslChannel(temp1, temp2, temp3) {
866
+ const temp3Min = 0, temp3Max = 1;
867
+ if (temp3 < temp3Min) {
868
+ temp3++;
869
+ }
870
+ if (temp3 > temp3Max) {
871
+ temp3--;
872
+ }
873
+ if (temp3 * sextuple < temp3Max) {
874
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
875
+ }
876
+ if (temp3 * double < temp3Max) {
877
+ return temp2;
878
+ }
879
+ if (temp3 * triple < temp3Max * double) {
880
+ const temp3Offset = double / triple;
881
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
882
+ }
883
+ return temp1;
884
+ }
1342
885
  function hslToRgb(hsl) {
1343
886
  const h = ((hsl.h % hMax) + hMax) % hMax, s = Math.max(sMin, Math.min(sMax, hsl.s)), l = Math.max(lMin, Math.min(lMax, hsl.l)), hNormalized = h / hMax, sNormalized = s / sMax, lNormalized = l / lMax;
1344
887
  if (s === sMin) {
1345
888
  const grayscaleValue = Math.round(lNormalized * rgbMax);
1346
889
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
1347
890
  }
1348
- const channel = (temp1, temp2, temp3) => {
1349
- const temp3Min = 0, temp3Max = 1;
1350
- if (temp3 < temp3Min) {
1351
- temp3++;
1352
- }
1353
- if (temp3 > temp3Max) {
1354
- temp3--;
1355
- }
1356
- if (temp3 * sextuple < temp3Max) {
1357
- return temp1 + (temp2 - temp1) * sextuple * temp3;
1358
- }
1359
- if (temp3 * double < temp3Max) {
1360
- return temp2;
1361
- }
1362
- if (temp3 * triple < temp3Max * double) {
1363
- const temp3Offset = double / triple;
1364
- return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1365
- }
1366
- return temp1;
1367
- }, temp1 = lNormalized < half
891
+ const temp1 = lNormalized < half
1368
892
  ? lNormalized * (sNormalizedOffset + sNormalized)
1369
- : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized - phaseThird));
893
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized - phaseThird));
1370
894
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
1371
895
  }
1372
896
  function getRandomRgbColor(min) {
@@ -1381,21 +905,18 @@ function getStyleFromRgb(color, hdr, opacity) {
1381
905
  const op = opacity ?? defaultOpacity, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1382
906
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
1383
907
  }
1384
- function getHdrStyleFromRgb(color, opacity) {
1385
- return `color(display-p3 ${(color.r / rgbMax).toString()} ${(color.g / rgbMax).toString()} ${(color.b / rgbMax).toString()} / ${(opacity ?? defaultOpacity).toString()})`;
908
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
909
+ const headroom = peakNits / sdrReferenceWhiteNits;
910
+ return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity).toString()})`;
1386
911
  }
1387
912
  function getSdrStyleFromRgb(color, opacity) {
1388
913
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity).toString()})`;
1389
914
  }
1390
915
  function getStyleFromHsl(color, hdr, opacity) {
1391
916
  const op = opacity ?? defaultOpacity, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1392
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity)));
1393
- }
1394
- function getHdrStyleFromHsl(color, opacity) {
1395
- return getHdrStyleFromRgb(hslToRgb(color), opacity);
1396
- }
1397
- function getSdrStyleFromHsl(color, opacity) {
1398
- return `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${(opacity ?? defaultOpacity).toString()})`;
917
+ return getCachedStyle(key, () => hdr
918
+ ? getStyleFromRgb(hslToRgb(color), true, opacity)
919
+ : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1399
920
  }
1400
921
  function getHslFromAnimation(animation) {
1401
922
  return animation === undefined
@@ -1468,7 +989,7 @@ class RenderManager {
1468
989
  return;
1469
990
  }
1470
991
  this.draw(ctx => {
1471
- clear(ctx, this.#canvasManager.size);
992
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
1472
993
  });
1473
994
  }
1474
995
  clear() {
@@ -1530,7 +1051,7 @@ class RenderManager {
1530
1051
  plugin.drawParticleSetup?.(context, particle, delta);
1531
1052
  }
1532
1053
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
1533
- drawParticle({
1054
+ this.#drawParticle({
1534
1055
  container,
1535
1056
  context,
1536
1057
  particle,
@@ -1549,7 +1070,7 @@ class RenderManager {
1549
1070
  drawParticlePlugins(particle, delta) {
1550
1071
  this.draw(ctx => {
1551
1072
  for (const plugin of this.#drawParticlePlugins) {
1552
- drawParticlePlugin(ctx, plugin, particle, delta);
1073
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
1553
1074
  }
1554
1075
  });
1555
1076
  }
@@ -1649,12 +1170,19 @@ class RenderManager {
1649
1170
  }
1650
1171
  paintBase(baseColor) {
1651
1172
  this.draw(ctx => {
1652
- paintBase(ctx, this.#canvasManager.size, baseColor);
1173
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
1174
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
1653
1175
  });
1654
1176
  }
1655
1177
  paintImage(image, opacity) {
1656
1178
  this.draw(ctx => {
1657
- paintImage(ctx, this.#canvasManager.size, image, opacity);
1179
+ if (!image) {
1180
+ return;
1181
+ }
1182
+ const prevAlpha = ctx.globalAlpha;
1183
+ ctx.globalAlpha = opacity;
1184
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
1185
+ ctx.globalAlpha = prevAlpha;
1658
1186
  });
1659
1187
  }
1660
1188
  setContext(context) {
@@ -1668,15 +1196,15 @@ class RenderManager {
1668
1196
  }
1669
1197
  stop() {
1670
1198
  this.draw(ctx => {
1671
- clear(ctx, this.#canvasManager.size);
1199
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
1672
1200
  });
1673
1201
  }
1674
- #applyPostDrawUpdaters = particle => {
1202
+ #applyPostDrawUpdaters(particle) {
1675
1203
  for (const updater of this.#postDrawUpdaters) {
1676
1204
  updater.afterDraw?.(particle);
1677
1205
  }
1678
- };
1679
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
1206
+ }
1207
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
1680
1208
  for (const updater of this.#preDrawUpdaters) {
1681
1209
  if (updater.getColorStyles) {
1682
1210
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -1695,8 +1223,114 @@ class RenderManager {
1695
1223
  }
1696
1224
  updater.beforeDraw?.(particle);
1697
1225
  }
1698
- };
1699
- #getPluginParticleColors = particle => {
1226
+ }
1227
+ #drawAfterEffect(drawer, data) {
1228
+ if (!drawer?.drawAfter) {
1229
+ return;
1230
+ }
1231
+ const { particle } = data;
1232
+ if (!particle.effect) {
1233
+ return;
1234
+ }
1235
+ drawer.drawAfter(data);
1236
+ }
1237
+ #drawBeforeEffect(drawer, data) {
1238
+ if (!drawer?.drawBefore) {
1239
+ return;
1240
+ }
1241
+ const { particle } = data;
1242
+ if (!particle.effect) {
1243
+ return;
1244
+ }
1245
+ drawer.drawBefore(data);
1246
+ }
1247
+ #drawParticle(data) {
1248
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
1249
+ x: pos.x,
1250
+ y: pos.y,
1251
+ };
1252
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
1253
+ if (colorStyles.fill) {
1254
+ context.fillStyle = colorStyles.fill;
1255
+ }
1256
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
1257
+ context.lineWidth = strokeWidth;
1258
+ if (colorStyles.stroke) {
1259
+ context.strokeStyle = colorStyles.stroke;
1260
+ }
1261
+ const drawData = {
1262
+ context,
1263
+ particle,
1264
+ radius,
1265
+ drawRadius: radius * drawScale,
1266
+ opacity,
1267
+ delta,
1268
+ pixelRatio: container.retina.pixelRatio,
1269
+ fill: fillEnabled,
1270
+ stroke: strokeWidth > minStrokeWidth,
1271
+ transformData,
1272
+ position: { ...pos },
1273
+ drawPosition,
1274
+ drawScale,
1275
+ };
1276
+ for (const plugin of container.plugins) {
1277
+ plugin.drawParticleTransform?.(drawData);
1278
+ }
1279
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
1280
+ this.#drawBeforeEffect(effect, drawData);
1281
+ this.#drawShapeBeforeDraw(shape, drawData);
1282
+ this.#drawShape(shape, drawData);
1283
+ this.#drawShapeAfterDraw(shape, drawData);
1284
+ this.#drawAfterEffect(effect, drawData);
1285
+ context.resetTransform();
1286
+ }
1287
+ #drawParticlePlugin(context, plugin, particle, delta) {
1288
+ if (!plugin.drawParticle) {
1289
+ return;
1290
+ }
1291
+ plugin.drawParticle(context, particle, delta);
1292
+ }
1293
+ #drawShape(drawer, data) {
1294
+ if (!drawer) {
1295
+ return;
1296
+ }
1297
+ const { context, fill, particle, stroke } = data;
1298
+ if (!particle.shape) {
1299
+ return;
1300
+ }
1301
+ context.beginPath();
1302
+ drawer.draw(data);
1303
+ if (particle.shapeClose) {
1304
+ context.closePath();
1305
+ }
1306
+ if (fill) {
1307
+ context.fill();
1308
+ }
1309
+ if (stroke) {
1310
+ context.stroke();
1311
+ }
1312
+ }
1313
+ #drawShapeAfterDraw(drawer, data) {
1314
+ if (!drawer?.afterDraw) {
1315
+ return;
1316
+ }
1317
+ const { particle } = data;
1318
+ if (!particle.shape) {
1319
+ return;
1320
+ }
1321
+ drawer.afterDraw(data);
1322
+ }
1323
+ #drawShapeBeforeDraw(drawer, data) {
1324
+ if (!drawer?.beforeDraw) {
1325
+ return;
1326
+ }
1327
+ const { particle } = data;
1328
+ if (!particle.shape) {
1329
+ return;
1330
+ }
1331
+ drawer.beforeDraw(data);
1332
+ }
1333
+ #getPluginParticleColors(particle) {
1700
1334
  let fColor, sColor;
1701
1335
  for (const plugin of this.#colorPlugins) {
1702
1336
  if (!fColor && plugin.particleFillColor) {
@@ -1712,7 +1346,7 @@ class RenderManager {
1712
1346
  this.#reusablePluginColors[fColorIndex] = fColor;
1713
1347
  this.#reusablePluginColors[sColorIndex] = sColor;
1714
1348
  return this.#reusablePluginColors;
1715
- };
1349
+ }
1716
1350
  }
1717
1351
 
1718
1352
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -1844,6 +1478,7 @@ class CanvasManager {
1844
1478
  obs.observe(element, { attributes: true });
1845
1479
  });
1846
1480
  this.initPlugins();
1481
+ this.#initContext();
1847
1482
  this.render.init();
1848
1483
  }
1849
1484
  initBackground() {
@@ -1853,7 +1488,7 @@ class CanvasManager {
1853
1488
  }
1854
1489
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
1855
1490
  if (color) {
1856
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
1491
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
1857
1492
  }
1858
1493
  else {
1859
1494
  elementStyle.backgroundColor = "";
@@ -1875,7 +1510,7 @@ class CanvasManager {
1875
1510
  if (this.#generated && this.domElement) {
1876
1511
  this.domElement.remove();
1877
1512
  }
1878
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
1513
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
1879
1514
  this.domElement = domCanvas;
1880
1515
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
1881
1516
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -1896,26 +1531,6 @@ class CanvasManager {
1896
1531
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
1897
1532
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
1898
1533
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
1899
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
1900
- this.render.setContextSettings({
1901
- alpha: true,
1902
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
1903
- desynchronized: true,
1904
- willReadFrequently: false,
1905
- });
1906
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
1907
- this.#safeMutationObserver(obs => {
1908
- obs.disconnect();
1909
- });
1910
- container.retina.init();
1911
- this.initBackground();
1912
- this.#safeMutationObserver(obs => {
1913
- const element = this.domElement;
1914
- if (!element || !(element instanceof Node)) {
1915
- return;
1916
- }
1917
- obs.observe(element, { attributes: true });
1918
- });
1919
1534
  }
1920
1535
  resize() {
1921
1536
  const element = this.domElement;
@@ -1983,12 +1598,30 @@ class CanvasManager {
1983
1598
  await container.refresh();
1984
1599
  }
1985
1600
  }
1986
- #applyResizePlugins = () => {
1601
+ #applyResizePlugins() {
1987
1602
  for (const plugin of this.#resizePlugins) {
1988
1603
  plugin.resize?.();
1989
1604
  }
1990
- };
1991
- #initStyle = () => {
1605
+ }
1606
+ #initContext() {
1607
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
1608
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
1609
+ safeMatchMedia("(dynamic-range: high)")?.matches;
1610
+ this.render.setContextSettings({
1611
+ alpha: true,
1612
+ desynchronized: true,
1613
+ willReadFrequently: false,
1614
+ ...(canSupportHdr
1615
+ ? { colorSpace: "display-p3", colorType: "float16" }
1616
+ : { colorSpace: "srgb" }),
1617
+ });
1618
+ const renderCanvas = this.renderCanvas;
1619
+ if (!renderCanvas) {
1620
+ return;
1621
+ }
1622
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
1623
+ }
1624
+ #initStyle() {
1992
1625
  const element = this.domElement, options = this.#container.actualOptions;
1993
1626
  if (!element) {
1994
1627
  return;
@@ -2009,8 +1642,8 @@ class CanvasManager {
2009
1642
  }
2010
1643
  element.style.setProperty(key, value, "important");
2011
1644
  }
2012
- };
2013
- #repairStyle = () => {
1645
+ }
1646
+ #repairStyle() {
2014
1647
  const element = this.domElement;
2015
1648
  if (!element) {
2016
1649
  return;
@@ -2029,27 +1662,27 @@ class CanvasManager {
2029
1662
  }
2030
1663
  observer.observe(element, { attributes: true });
2031
1664
  });
2032
- };
2033
- #resetOriginalStyle = () => {
1665
+ }
1666
+ #resetOriginalStyle() {
2034
1667
  const element = this.domElement, originalStyle = this.#originalStyle;
2035
1668
  if (!element || !originalStyle) {
2036
1669
  return;
2037
1670
  }
2038
1671
  setStyle(element, originalStyle, true);
2039
- };
2040
- #safeMutationObserver = callback => {
1672
+ }
1673
+ #safeMutationObserver(callback) {
2041
1674
  if (!this.#mutationObserver) {
2042
1675
  return;
2043
1676
  }
2044
1677
  callback(this.#mutationObserver);
2045
- };
2046
- #setFullScreenStyle = () => {
1678
+ }
1679
+ #setFullScreenStyle() {
2047
1680
  const element = this.domElement;
2048
1681
  if (!element) {
2049
1682
  return;
2050
1683
  }
2051
1684
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
2052
- };
1685
+ }
2053
1686
  }
2054
1687
 
2055
1688
  class EventListeners {
@@ -2074,7 +1707,7 @@ class EventListeners {
2074
1707
  removeListeners() {
2075
1708
  this.#manageListeners(false);
2076
1709
  }
2077
- #handleVisibilityChange = () => {
1710
+ #handleVisibilityChange() {
2078
1711
  const container = this.#container, options = container.actualOptions;
2079
1712
  if (!options.pauseOnBlur) {
2080
1713
  return;
@@ -2092,8 +1725,8 @@ class EventListeners {
2092
1725
  container.draw(true);
2093
1726
  }
2094
1727
  }
2095
- };
2096
- #handleWindowResize = () => {
1728
+ }
1729
+ #handleWindowResize() {
2097
1730
  if (this.#resizeTimeout) {
2098
1731
  clearTimeout(this.#resizeTimeout);
2099
1732
  this.#resizeTimeout = undefined;
@@ -2103,13 +1736,13 @@ class EventListeners {
2103
1736
  await canvas.windowResize();
2104
1737
  };
2105
1738
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
2106
- };
2107
- #manageListeners = add => {
1739
+ }
1740
+ #manageListeners(add) {
2108
1741
  const handlers = this.#handlers;
2109
1742
  this.#manageResize(add);
2110
1743
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
2111
- };
2112
- #manageResize = add => {
1744
+ }
1745
+ #manageResize(add) {
2113
1746
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
2114
1747
  if (!options.resize.enable) {
2115
1748
  return;
@@ -2136,7 +1769,7 @@ class EventListeners {
2136
1769
  });
2137
1770
  this.#resizeObserver.observe(canvasEl);
2138
1771
  }
2139
- };
1772
+ }
2140
1773
  }
2141
1774
 
2142
1775
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -2163,6 +1796,131 @@ function fixOutMode(data) {
2163
1796
  data.setCb(data.radius);
2164
1797
  }
2165
1798
  }
1799
+ function normalizeAngle(angle, modulus) {
1800
+ const normalized = angle % modulus;
1801
+ return normalized < defaultAngle ? normalized + modulus : normalized;
1802
+ }
1803
+ function initParticleState(particle, id, group) {
1804
+ particle.id = id;
1805
+ particle.group = group;
1806
+ particle.justWarped = false;
1807
+ particle.effectClose = true;
1808
+ particle.shapeClose = true;
1809
+ particle.pathRotation = false;
1810
+ particle.lastPathTime = 0;
1811
+ particle.destroyed = false;
1812
+ particle.unbreakable = false;
1813
+ particle.isRotating = false;
1814
+ particle.rotation = 0;
1815
+ particle.misplaced = false;
1816
+ particle.retina = {
1817
+ maxDistance: {},
1818
+ maxSpeed: 0,
1819
+ moveDrift: 0,
1820
+ moveSpeed: 0,
1821
+ sizeAnimationSpeed: 0,
1822
+ };
1823
+ particle.size = {
1824
+ value: 1,
1825
+ max: 1,
1826
+ min: 1,
1827
+ enable: false,
1828
+ };
1829
+ particle.outType = ParticleOutType.normal;
1830
+ particle.ignoresResizeRatio = true;
1831
+ }
1832
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
1833
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
1834
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
1835
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
1836
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
1837
+ if (overrideOptions) {
1838
+ if (overrideOptions.effect) {
1839
+ const overrideEffectType = overrideOptions.effect.type;
1840
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
1841
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
1842
+ if (effect) {
1843
+ particle.effect = effect;
1844
+ }
1845
+ }
1846
+ effectOptions.load(overrideOptions.effect);
1847
+ }
1848
+ if (overrideOptions.shape) {
1849
+ const overrideShapeType = overrideOptions.shape.type;
1850
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
1851
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
1852
+ if (shape) {
1853
+ particle.shape = shape;
1854
+ }
1855
+ }
1856
+ shapeOptions.load(overrideOptions.shape);
1857
+ }
1858
+ }
1859
+ if (particle.effect === randomColorValue) {
1860
+ const availableEffects = [...container.effectDrawers.keys()];
1861
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
1862
+ }
1863
+ if (particle.shape === randomColorValue) {
1864
+ const availableShapes = [...container.shapeDrawers.keys()];
1865
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
1866
+ }
1867
+ particle.effectData = particle.effect
1868
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
1869
+ : undefined;
1870
+ particle.shapeData = particle.shape
1871
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
1872
+ : undefined;
1873
+ particlesOptions.load(overrideOptions);
1874
+ const effectData = particle.effectData, shapeData = particle.shapeData;
1875
+ if (effectData) {
1876
+ particlesOptions.load(effectData.particles);
1877
+ }
1878
+ if (shapeData) {
1879
+ particlesOptions.load(shapeData.particles);
1880
+ }
1881
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
1882
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
1883
+ return particlesOptions;
1884
+ }
1885
+ function initParticleDrawers(particle, container) {
1886
+ let effectDrawer, shapeDrawer;
1887
+ if (particle.effect) {
1888
+ effectDrawer = container.effectDrawers.get(particle.effect);
1889
+ }
1890
+ if (effectDrawer?.loadEffect) {
1891
+ effectDrawer.loadEffect(particle);
1892
+ }
1893
+ if (particle.shape) {
1894
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
1895
+ }
1896
+ if (shapeDrawer?.loadShape) {
1897
+ shapeDrawer.loadShape(particle);
1898
+ }
1899
+ const sideCountFunc = shapeDrawer?.getSidesCount;
1900
+ if (sideCountFunc) {
1901
+ particle.sides = sideCountFunc(particle);
1902
+ }
1903
+ }
1904
+ function runUpdaterPreInit(updaters, particle) {
1905
+ for (const updater of updaters) {
1906
+ updater.preInit?.(particle);
1907
+ }
1908
+ }
1909
+ function runUpdaterInit(updaters, particle) {
1910
+ for (const updater of updaters) {
1911
+ updater.init(particle);
1912
+ }
1913
+ }
1914
+ function runDrawerInit(container, particle) {
1915
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
1916
+ effectDrawer?.particleInit?.(container, particle);
1917
+ shapeDrawer?.particleInit?.(container, particle);
1918
+ }
1919
+ function runParticleCreatedPlugins(container, particle) {
1920
+ for (const plugin of container.particleCreatedPlugins) {
1921
+ plugin.particleCreated?.(particle);
1922
+ }
1923
+ }
2166
1924
  class Particle {
2167
1925
  backColor;
2168
1926
  bubble;
@@ -2298,84 +2056,10 @@ class Particle {
2298
2056
  }
2299
2057
  init(id, position, overrideOptions, group) {
2300
2058
  const container = this.#container;
2301
- this.id = id;
2302
- this.group = group;
2303
- this.justWarped = false;
2304
- this.effectClose = true;
2305
- this.shapeClose = true;
2306
- this.pathRotation = false;
2307
- this.lastPathTime = 0;
2308
- this.destroyed = false;
2309
- this.unbreakable = false;
2310
- this.isRotating = false;
2311
- this.rotation = 0;
2312
- this.misplaced = false;
2313
- this.retina = {
2314
- maxDistance: {},
2315
- maxSpeed: 0,
2316
- moveDrift: 0,
2317
- moveSpeed: 0,
2318
- sizeAnimationSpeed: 0,
2319
- };
2320
- this.size = {
2321
- value: 1,
2322
- max: 1,
2323
- min: 1,
2324
- enable: false,
2325
- };
2326
- this.outType = ParticleOutType.normal;
2327
- this.ignoresResizeRatio = true;
2328
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
2329
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
2330
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
2331
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
2332
- if (overrideOptions) {
2333
- if (overrideOptions.effect) {
2334
- const overrideEffectType = overrideOptions.effect.type;
2335
- if (overrideEffectType && overrideEffectType !== this.effect) {
2336
- const effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
2337
- if (effect) {
2338
- this.effect = effect;
2339
- }
2340
- }
2341
- effectOptions.load(overrideOptions.effect);
2342
- }
2343
- if (overrideOptions.shape) {
2344
- const overrideShapeType = overrideOptions.shape.type;
2345
- if (overrideShapeType && overrideShapeType !== this.shape) {
2346
- const shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
2347
- if (shape) {
2348
- this.shape = shape;
2349
- }
2350
- }
2351
- shapeOptions.load(overrideOptions.shape);
2352
- }
2353
- }
2354
- if (this.effect === randomColorValue) {
2355
- const availableEffects = [...this.#container.effectDrawers.keys()];
2356
- this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
2357
- }
2358
- if (this.shape === randomColorValue) {
2359
- const availableShapes = [...this.#container.shapeDrawers.keys()];
2360
- this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
2361
- }
2362
- this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
2363
- this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
2364
- particlesOptions.load(overrideOptions);
2365
- const effectData = this.effectData, shapeData = this.shapeData;
2366
- if (effectData) {
2367
- particlesOptions.load(effectData.particles);
2368
- }
2369
- if (shapeData) {
2370
- particlesOptions.load(shapeData.particles);
2371
- }
2372
- this.effectClose = effectData?.close ?? particlesOptions.effect.close;
2373
- this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
2374
- this.options = particlesOptions;
2059
+ initParticleState(this, id, group);
2060
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
2375
2061
  container.retina.initParticle(this);
2376
- for (const updater of container.particleUpdaters) {
2377
- updater.preInit?.(this);
2378
- }
2062
+ runUpdaterPreInit(container.particleUpdaters, this);
2379
2063
  this.bubble = {
2380
2064
  inRange: false,
2381
2065
  };
@@ -2388,32 +2072,11 @@ class Particle {
2388
2072
  this.velocity = this.initialVelocity.copy();
2389
2073
  this.zIndexFactor = this.position.z / container.zLayers;
2390
2074
  this.sides = 24;
2391
- let effectDrawer, shapeDrawer;
2392
- if (this.effect) {
2393
- effectDrawer = container.effectDrawers.get(this.effect);
2394
- }
2395
- if (effectDrawer?.loadEffect) {
2396
- effectDrawer.loadEffect(this);
2397
- }
2398
- if (this.shape) {
2399
- shapeDrawer = container.shapeDrawers.get(this.shape);
2400
- }
2401
- if (shapeDrawer?.loadShape) {
2402
- shapeDrawer.loadShape(this);
2403
- }
2404
- const sideCountFunc = shapeDrawer?.getSidesCount;
2405
- if (sideCountFunc) {
2406
- this.sides = sideCountFunc(this);
2407
- }
2075
+ initParticleDrawers(this, container);
2408
2076
  this.spawning = false;
2409
- for (const updater of container.particleUpdaters) {
2410
- updater.init(this);
2411
- }
2412
- effectDrawer?.particleInit?.(container, this);
2413
- shapeDrawer?.particleInit?.(container, this);
2414
- for (const plugin of container.particleCreatedPlugins) {
2415
- plugin.particleCreated?.(this);
2416
- }
2077
+ runUpdaterInit(container.particleUpdaters, this);
2078
+ runDrawerInit(container, this);
2079
+ runParticleCreatedPlugins(container, this);
2417
2080
  }
2418
2081
  isInsideCanvas(direction) {
2419
2082
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -2427,15 +2090,15 @@ class Particle {
2427
2090
  }
2428
2091
  const angle = this.roll.angle;
2429
2092
  if (this.roll.horizontal && this.roll.vertical) {
2430
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
2093
+ const adjustedAngle = normalizeAngle(angle, doublePI);
2431
2094
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
2432
2095
  }
2433
2096
  if (this.roll.horizontal) {
2434
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
2097
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
2435
2098
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
2436
2099
  }
2437
2100
  if (this.roll.vertical) {
2438
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
2101
+ const adjustedAngle = normalizeAngle(angle, doublePI);
2439
2102
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
2440
2103
  }
2441
2104
  return false;
@@ -2448,10 +2111,10 @@ class Particle {
2448
2111
  updater.reset?.(this);
2449
2112
  }
2450
2113
  }
2451
- #calcPosition = (position, zIndex) => {
2114
+ #calcPosition(position, zIndex) {
2452
2115
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
2453
- const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
2454
- while (!signal.aborted) {
2116
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
2117
+ for (;;) {
2455
2118
  for (const plugin of plugins) {
2456
2119
  const pluginPos = plugin.particlePosition?.(posVec, this);
2457
2120
  if (pluginPos) {
@@ -2479,9 +2142,8 @@ class Particle {
2479
2142
  tryCount += tryCountIncrement;
2480
2143
  posVec = undefined;
2481
2144
  }
2482
- return posVec;
2483
- };
2484
- #calculateVelocity = () => {
2145
+ }
2146
+ #calculateVelocity() {
2485
2147
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
2486
2148
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
2487
2149
  return res;
@@ -2497,8 +2159,8 @@ class Particle {
2497
2159
  res.length *= getRandom();
2498
2160
  }
2499
2161
  return res;
2500
- };
2501
- #fixHorizontal = (pos, radius, outMode) => {
2162
+ }
2163
+ #fixHorizontal(pos, radius, outMode) {
2502
2164
  fixOutMode({
2503
2165
  outMode,
2504
2166
  checkModes: [OutMode.bounce],
@@ -2507,8 +2169,8 @@ class Particle {
2507
2169
  setCb: (value) => (pos.x += value),
2508
2170
  radius,
2509
2171
  });
2510
- };
2511
- #fixVertical = (pos, radius, outMode) => {
2172
+ }
2173
+ #fixVertical(pos, radius, outMode) {
2512
2174
  fixOutMode({
2513
2175
  outMode,
2514
2176
  checkModes: [OutMode.bounce],
@@ -2517,8 +2179,8 @@ class Particle {
2517
2179
  setCb: (value) => (pos.y += value),
2518
2180
  radius,
2519
2181
  });
2520
- };
2521
- #getDefaultInsideCanvasResult = (direction, outMode) => {
2182
+ }
2183
+ #getDefaultInsideCanvasResult(direction, outMode) {
2522
2184
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
2523
2185
  if (direction === OutModeDirection.bottom) {
2524
2186
  return {
@@ -2551,8 +2213,8 @@ class Particle {
2551
2213
  position.x <= canvasSize.width + radius,
2552
2214
  reason: "default",
2553
2215
  };
2554
- };
2555
- #getInsideCanvasCallbackData = (direction, outMode) => {
2216
+ }
2217
+ #getInsideCanvasCallbackData(direction, outMode) {
2556
2218
  return {
2557
2219
  canvasSize: this.#container.canvas.size,
2558
2220
  direction,
@@ -2560,8 +2222,8 @@ class Particle {
2560
2222
  particle: this,
2561
2223
  radius: this.getRadius(),
2562
2224
  };
2563
- };
2564
- #getInsideCanvasResult = (data) => {
2225
+ }
2226
+ #getInsideCanvasResult(data) {
2565
2227
  const defaultResult = this.#getDefaultInsideCanvasResult(data.direction, data.outMode), container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined, effectDrawer = this.effect ? container.effectDrawers.get(this.effect) : undefined, shapeCheck = shapeDrawer?.isInsideCanvas, effectCheck = effectDrawer?.isInsideCanvas;
2566
2228
  if (!shapeCheck && !effectCheck) {
2567
2229
  return defaultResult;
@@ -2576,8 +2238,8 @@ class Particle {
2576
2238
  };
2577
2239
  }
2578
2240
  return shapeResult ?? effectResult ?? defaultResult;
2579
- };
2580
- #getRollColor = color => {
2241
+ }
2242
+ #getRollColor(color) {
2581
2243
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
2582
2244
  return color;
2583
2245
  }
@@ -2591,8 +2253,8 @@ class Particle {
2591
2253
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
2592
2254
  }
2593
2255
  return color;
2594
- };
2595
- #initPosition = position => {
2256
+ }
2257
+ #initPosition(position) {
2596
2258
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
2597
2259
  if (!initialPosition) {
2598
2260
  throw new Error("a valid position cannot be found for particle");
@@ -2615,8 +2277,8 @@ class Particle {
2615
2277
  break;
2616
2278
  }
2617
2279
  this.offset = Vector.origin;
2618
- };
2619
- #normalizeInsideCanvasResult = (result, reason) => {
2280
+ }
2281
+ #normalizeInsideCanvasResult(result, reason) {
2620
2282
  if (typeof result === "boolean") {
2621
2283
  return {
2622
2284
  inside: result,
@@ -2628,7 +2290,7 @@ class Particle {
2628
2290
  margin: result.margin,
2629
2291
  reason: result.reason ?? reason,
2630
2292
  };
2631
- };
2293
+ }
2632
2294
  }
2633
2295
 
2634
2296
  class SpatialHashGrid {
@@ -2981,10 +2643,10 @@ class ParticlesManager {
2981
2643
  }
2982
2644
  this.#resizeFactor = undefined;
2983
2645
  }
2984
- #addToPool = (...particles) => {
2646
+ #addToPool(...particles) {
2985
2647
  this.#pool.push(...particles);
2986
- };
2987
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
2648
+ }
2649
+ #applyDensity(options, pluginsCount, group, groupOptions) {
2988
2650
  const numberOptions = options.number;
2989
2651
  if (!numberOptions.density.enable) {
2990
2652
  if (group === undefined) {
@@ -3008,36 +2670,19 @@ class ParticlesManager {
3008
2670
  else if (particlesCount > particlesNumber) {
3009
2671
  this.removeQuantity(particlesCount - particlesNumber, group);
3010
2672
  }
3011
- };
3012
- #createBuckets = (zLayers) => {
2673
+ }
2674
+ #createBuckets(zLayers) {
3013
2675
  const bucketCount = Math.max(Math.floor(zLayers), one);
3014
2676
  return Array.from({ length: bucketCount }, () => []);
3015
- };
3016
- #getBucketIndex = (zIndex) => {
2677
+ }
2678
+ #getBucketIndex(zIndex) {
3017
2679
  const maxBucketIndex = this.#zBuckets.length - one;
3018
2680
  if (maxBucketIndex <= minIndex) {
3019
2681
  return minIndex;
3020
2682
  }
3021
2683
  return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
3022
- };
3023
- #getParticleInsertIndex = (bucket, particleId) => {
3024
- let start = minIndex, end = bucket.length;
3025
- while (start < end) {
3026
- const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
3027
- if (!middleParticle) {
3028
- end = middle;
3029
- continue;
3030
- }
3031
- if (middleParticle.id < particleId) {
3032
- start = middle + one;
3033
- }
3034
- else {
3035
- end = middle;
3036
- }
3037
- }
3038
- return start;
3039
- };
3040
- #initDensityFactor = densityOptions => {
2684
+ }
2685
+ #initDensityFactor(densityOptions) {
3041
2686
  const container = this.#container;
3042
2687
  if (!densityOptions.enable) {
3043
2688
  return defaultDensityFactor;
@@ -3047,16 +2692,16 @@ class ParticlesManager {
3047
2692
  return defaultDensityFactor;
3048
2693
  }
3049
2694
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
3050
- };
3051
- #insertParticleIntoBucket = (particle) => {
2695
+ }
2696
+ #insertParticleIntoBucket(particle) {
3052
2697
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
3053
2698
  if (!bucket) {
3054
2699
  return;
3055
2700
  }
3056
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
2701
+ bucket.push(particle);
3057
2702
  this.#particleBuckets.set(particle.id, bucketIndex);
3058
- };
3059
- #removeParticle = (index, group, override) => {
2703
+ }
2704
+ #removeParticle(index, group, override) {
3060
2705
  const particle = this.#array[index];
3061
2706
  if (!particle) {
3062
2707
  return false;
@@ -3072,22 +2717,20 @@ class ParticlesManager {
3072
2717
  });
3073
2718
  this.#addToPool(particle);
3074
2719
  return true;
3075
- };
3076
- #removeParticleFromBucket = (particle) => {
2720
+ }
2721
+ #removeParticleFromBucket(particle) {
3077
2722
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
3078
2723
  if (!bucket) {
3079
2724
  this.#particleBuckets.delete(particle.id);
3080
2725
  return;
3081
2726
  }
3082
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
3083
- if (bucket[particleIndex]?.id !== particle.id) {
3084
- this.#particleBuckets.delete(particle.id);
3085
- return;
2727
+ const idx = bucket.findIndex(p => p.id === particle.id);
2728
+ if (idx >= minIndex) {
2729
+ bucket.splice(idx, deleteCount);
3086
2730
  }
3087
- bucket.splice(particleIndex, deleteCount);
3088
2731
  this.#particleBuckets.delete(particle.id);
3089
- };
3090
- #resetBuckets = (zLayers) => {
2732
+ }
2733
+ #resetBuckets(zLayers) {
3091
2734
  const bucketCount = Math.max(Math.floor(zLayers), one);
3092
2735
  if (this.#zBuckets.length !== bucketCount) {
3093
2736
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -3096,8 +2739,8 @@ class ParticlesManager {
3096
2739
  for (const bucket of this.#zBuckets) {
3097
2740
  bucket.length = minIndex;
3098
2741
  }
3099
- };
3100
- #updateParticleBucket = (particle) => {
2742
+ }
2743
+ #updateParticleBucket(particle) {
3101
2744
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
3102
2745
  if (currentBucketIndex === undefined) {
3103
2746
  this.#insertParticleIntoBucket(particle);
@@ -3108,9 +2751,9 @@ class ParticlesManager {
3108
2751
  }
3109
2752
  const currentBucket = this.#zBuckets[currentBucketIndex];
3110
2753
  if (currentBucket) {
3111
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
3112
- if (currentBucket[particleIndex]?.id === particle.id) {
3113
- currentBucket.splice(particleIndex, deleteCount);
2754
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
2755
+ if (idx >= minIndex) {
2756
+ currentBucket.splice(idx, deleteCount);
3114
2757
  }
3115
2758
  }
3116
2759
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -3118,10 +2761,16 @@ class ParticlesManager {
3118
2761
  this.#particleBuckets.set(particle.id, newBucketIndex);
3119
2762
  return;
3120
2763
  }
3121
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
2764
+ newBucket.push(particle);
2765
+ if (newBucket.length >= double) {
2766
+ const prev = newBucket[newBucket.length - double];
2767
+ if (prev && particle.id < prev.id) {
2768
+ newBucket.sort((a, b) => a.id - b.id);
2769
+ }
2770
+ }
3122
2771
  this.#particleBuckets.set(particle.id, newBucketIndex);
3123
- };
3124
- #updateParticlesPhase1 = (delta) => {
2772
+ }
2773
+ #updateParticlesPhase1(delta) {
3125
2774
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
3126
2775
  for (const particle of this.#array) {
3127
2776
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -3147,8 +2796,8 @@ class ParticlesManager {
3147
2796
  this.grid.insert(particle);
3148
2797
  }
3149
2798
  return particlesToDelete;
3150
- };
3151
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
2799
+ }
2800
+ #updateParticlesPhase2(delta, particlesToDelete) {
3152
2801
  for (const particle of this.#array) {
3153
2802
  if (particle.destroyed) {
3154
2803
  particlesToDelete.add(particle);
@@ -3164,7 +2813,7 @@ class ParticlesManager {
3164
2813
  }
3165
2814
  this.#updateParticleBucket(particle);
3166
2815
  }
3167
- };
2816
+ }
3168
2817
  }
3169
2818
 
3170
2819
  class Retina {
@@ -3526,7 +3175,7 @@ class Container {
3526
3175
  }
3527
3176
  return refresh;
3528
3177
  }
3529
- #nextFrame = (timestamp) => {
3178
+ #nextFrame(timestamp) {
3530
3179
  try {
3531
3180
  if (!this.#smooth &&
3532
3181
  this.#lastFrameTime !== undefined &&
@@ -3554,7 +3203,7 @@ class Container {
3554
3203
  catch (e) {
3555
3204
  getLogger().error("error in animation loop", e);
3556
3205
  }
3557
- };
3206
+ }
3558
3207
  }
3559
3208
 
3560
3209
  export { Container };