@tsparticles/stencil 4.1.3 → 4.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.
- package/README.md +13 -0
- package/dist/cjs/{Container-0BqPfTsu.js → Container-CGxn4Tv3.js} +659 -1010
- package/dist/cjs/{index-Bw7g3biq.js → index-7q-LddLf.js} +57 -160
- package/dist/cjs/{index-B2lLThjb.js → index-BjS63OiI.js} +95 -5
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/stencil-particles.cjs.entry.js +23 -6
- package/dist/cjs/tsparticlesstencil.cjs.js +2 -2
- package/dist/collection/components/stencil-particles/stencil-particles.js +83 -4
- package/dist/esm/{Container-BxLt611H.js → Container-BWWTh10Z.js} +659 -1010
- package/dist/esm/{index-DKFk70aj.js → index-PhwiK2_P.js} +95 -6
- package/dist/esm/{index-BXzC9NH1.js → index-aPxdqzSw.js} +57 -160
- package/dist/esm/index.js +1 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/stencil-particles.entry.js +23 -6
- package/dist/esm/tsparticlesstencil.js +3 -3
- package/dist/tsparticlesstencil/index.esm.js +1 -1
- package/dist/tsparticlesstencil/p-FNL2LsWF.js +1 -0
- package/dist/tsparticlesstencil/p-PBQ5N1xQ.js +1 -0
- package/dist/tsparticlesstencil/p-PhwiK2_P.js +2 -0
- package/dist/tsparticlesstencil/p-e16c4912.entry.js +1 -0
- package/dist/tsparticlesstencil/tsparticlesstencil.esm.js +1 -1
- package/dist/types/components/stencil-particles/stencil-particles.d.ts +6 -2
- package/dist/types/components.d.ts +24 -2
- package/package.json +8 -7
- package/dist/tsparticlesstencil/p-BhGs05ap.js +0 -1
- package/dist/tsparticlesstencil/p-DKFk70aj.js +0 -2
- package/dist/tsparticlesstencil/p-LyLjQmWv.js +0 -1
- 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
|
|
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-aPxdqzSw.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
|
|
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
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
128
|
-
super.
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
206
|
-
super.
|
|
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
|
-
|
|
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
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
|
|
267
|
-
this.enable
|
|
268
|
-
this.zIndex
|
|
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
|
-
|
|
287
|
-
this
|
|
288
|
-
this.enable
|
|
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
|
-
|
|
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
|
-
|
|
326
|
-
|
|
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
|
-
|
|
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
|
-
|
|
350
|
-
|
|
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
|
-
|
|
362
|
-
this.offset
|
|
363
|
-
this.value
|
|
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
|
-
|
|
384
|
-
this.x
|
|
385
|
-
this.y
|
|
386
|
-
this
|
|
387
|
-
this.radius
|
|
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
|
-
|
|
414
|
-
this
|
|
415
|
-
this.enable
|
|
416
|
-
this.inverse
|
|
417
|
-
this.maxSpeed
|
|
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
|
-
|
|
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
|
-
|
|
460
|
-
this.clamp
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
511
|
-
this.acceleration
|
|
512
|
-
this.enable
|
|
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
|
-
|
|
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
|
-
|
|
574
|
-
|
|
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
|
-
|
|
588
|
-
|
|
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
|
-
|
|
607
|
-
|
|
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
|
-
|
|
617
|
-
|
|
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
|
-
|
|
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
|
-
|
|
643
|
-
|
|
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
|
-
|
|
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
|
-
|
|
663
|
-
|
|
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
|
-
|
|
675
|
-
super();
|
|
676
|
-
this.value = 1;
|
|
677
|
-
}
|
|
453
|
+
value = 1;
|
|
678
454
|
}
|
|
679
455
|
|
|
680
|
-
class ParticlesBounce {
|
|
681
|
-
horizontal;
|
|
682
|
-
vertical;
|
|
683
|
-
|
|
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
|
-
|
|
701
|
-
this.enable
|
|
702
|
-
this.width
|
|
703
|
-
this.height
|
|
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
|
-
|
|
727
|
-
this
|
|
728
|
-
this.value
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
787
|
-
|
|
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
|
-
|
|
800
|
-
super();
|
|
801
|
-
this.opacityRate
|
|
802
|
-
this.sizeRate
|
|
803
|
-
this.velocityRate
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
1220
|
-
|
|
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(),
|
|
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
|
|
1238
|
-
|
|
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
|
|
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 *
|
|
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
|
-
|
|
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, () =>
|
|
1393
|
-
|
|
1394
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1199
|
+
ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
|
|
1672
1200
|
});
|
|
1673
1201
|
}
|
|
1674
|
-
#applyPostDrawUpdaters
|
|
1202
|
+
#applyPostDrawUpdaters(particle) {
|
|
1675
1203
|
for (const updater of this.#postDrawUpdaters) {
|
|
1676
1204
|
updater.afterDraw?.(particle);
|
|
1677
1205
|
}
|
|
1678
|
-
}
|
|
1679
|
-
#applyPreDrawUpdaters
|
|
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
|
-
#
|
|
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
|
|
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
|
-
#
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2302
|
-
this.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2410
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2454
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
2646
|
+
#addToPool(...particles) {
|
|
2985
2647
|
this.#pool.push(...particles);
|
|
2986
|
-
}
|
|
2987
|
-
#applyDensity
|
|
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
|
|
2673
|
+
}
|
|
2674
|
+
#createBuckets(zLayers) {
|
|
3013
2675
|
const bucketCount = Math.max(Math.floor(zLayers), one);
|
|
3014
2676
|
return Array.from({ length: bucketCount }, () => []);
|
|
3015
|
-
}
|
|
3016
|
-
#getBucketIndex
|
|
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
|
-
#
|
|
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
|
|
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.
|
|
2701
|
+
bucket.push(particle);
|
|
3057
2702
|
this.#particleBuckets.set(particle.id, bucketIndex);
|
|
3058
|
-
}
|
|
3059
|
-
#removeParticle
|
|
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
|
|
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
|
|
3083
|
-
if (
|
|
3084
|
-
|
|
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
|
|
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
|
|
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
|
|
3112
|
-
if (
|
|
3113
|
-
currentBucket.splice(
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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 };
|