@tsparticles/stencil 4.1.2 → 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-BB03Liy1.js → Container-CGxn4Tv3.js} +693 -1038
- package/dist/cjs/{index-WCJ4NcqE.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-C5hHCYio.js → Container-BWWTh10Z.js} +693 -1038
- package/dist/esm/{index-DKFk70aj.js → index-PhwiK2_P.js} +95 -6
- package/dist/esm/{index-DYnEUqIm.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-4488fb9d.entry.js +0 -1
- package/dist/tsparticlesstencil/p-C8gVqIeD.js +0 -1
- package/dist/tsparticlesstencil/p-DKFk70aj.js +0 -2
- package/dist/tsparticlesstencil/p-h0XxhONB.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,289 +649,117 @@ 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 => {
|
|
1023
698
|
this.#importPreset(preset);
|
|
1024
699
|
});
|
|
1025
700
|
}
|
|
1026
|
-
if (data.palette !== undefined) {
|
|
1027
|
-
this.palette = data.palette;
|
|
1028
|
-
this.#importPalette(this.palette);
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
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
|
-
}
|
|
1068
|
-
this.background.load(data.background);
|
|
1069
|
-
const fullScreen = data.fullScreen;
|
|
1070
|
-
if (isBoolean(fullScreen)) {
|
|
1071
|
-
this.fullScreen.enable = fullScreen;
|
|
1072
|
-
}
|
|
1073
|
-
else {
|
|
1074
|
-
this.fullScreen.load(fullScreen);
|
|
1075
|
-
}
|
|
1076
|
-
this.particles.load(data.particles);
|
|
1077
|
-
this.resize.load(data.resize);
|
|
1078
|
-
this.style = deepExtend(this.style, data.style);
|
|
1079
|
-
if (data.smooth !== undefined) {
|
|
1080
|
-
this.smooth = data.smooth;
|
|
1081
|
-
}
|
|
1082
|
-
this.#pluginManager.plugins.forEach(plugin => {
|
|
1083
|
-
plugin.loadOptions(this.#container, this, data);
|
|
1084
|
-
});
|
|
1085
|
-
}
|
|
1086
|
-
#importPalette = palette => {
|
|
1087
|
-
const paletteData = this.#pluginManager.getPalette(palette);
|
|
1088
|
-
if (!paletteData) {
|
|
1089
|
-
return;
|
|
1090
|
-
}
|
|
1091
|
-
this.load({
|
|
1092
|
-
background: {
|
|
1093
|
-
color: paletteData.background,
|
|
1094
|
-
},
|
|
1095
|
-
blend: {
|
|
1096
|
-
enable: true,
|
|
1097
|
-
mode: paletteData.blendMode,
|
|
1098
|
-
},
|
|
1099
|
-
particles: {
|
|
1100
|
-
palette,
|
|
1101
|
-
},
|
|
1102
|
-
});
|
|
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;
|
|
701
|
+
if (data.palette !== undefined) {
|
|
702
|
+
this.palette = data.palette;
|
|
703
|
+
this.#importPalette(this.palette);
|
|
704
|
+
}
|
|
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);
|
|
717
|
+
this.background.load(data.background);
|
|
718
|
+
const fullScreen = data.fullScreen;
|
|
719
|
+
if (isBoolean(fullScreen)) {
|
|
720
|
+
this.fullScreen.enable = fullScreen;
|
|
721
|
+
}
|
|
722
|
+
else {
|
|
723
|
+
this.fullScreen.load(fullScreen);
|
|
724
|
+
}
|
|
725
|
+
this.particles.load(data.particles);
|
|
726
|
+
this.resize.load(data.resize);
|
|
727
|
+
this.style = deepExtend(this.style, data.style);
|
|
728
|
+
loadProperty(this, "smooth", data.smooth);
|
|
729
|
+
this.#pluginManager.plugins.forEach(plugin => {
|
|
730
|
+
plugin.loadOptions(this.#container, this, data);
|
|
731
|
+
});
|
|
1218
732
|
}
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
733
|
+
#importPalette(palette) {
|
|
734
|
+
const paletteData = this.#pluginManager.getPalette(palette);
|
|
735
|
+
if (!paletteData) {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
this.load({
|
|
739
|
+
background: {
|
|
740
|
+
color: paletteData.background,
|
|
741
|
+
},
|
|
742
|
+
blend: {
|
|
743
|
+
enable: true,
|
|
744
|
+
mode: paletteData.blendMode,
|
|
745
|
+
},
|
|
746
|
+
particles: {
|
|
747
|
+
palette,
|
|
748
|
+
},
|
|
749
|
+
});
|
|
1222
750
|
}
|
|
1223
|
-
|
|
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,78 +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?.type && overrideOptions.effect.type !== this.effect) {
|
|
2334
|
-
const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
|
|
2335
|
-
if (effect) {
|
|
2336
|
-
this.effect = effect;
|
|
2337
|
-
effectOptions.load(overrideOptions.effect);
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
if (overrideOptions.shape?.type && overrideOptions.shape.type !== this.shape) {
|
|
2341
|
-
const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
|
|
2342
|
-
if (shape) {
|
|
2343
|
-
this.shape = shape;
|
|
2344
|
-
shapeOptions.load(overrideOptions.shape);
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
}
|
|
2348
|
-
if (this.effect === randomColorValue) {
|
|
2349
|
-
const availableEffects = [...this.#container.effectDrawers.keys()];
|
|
2350
|
-
this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
|
|
2351
|
-
}
|
|
2352
|
-
if (this.shape === randomColorValue) {
|
|
2353
|
-
const availableShapes = [...this.#container.shapeDrawers.keys()];
|
|
2354
|
-
this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
|
|
2355
|
-
}
|
|
2356
|
-
this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
|
|
2357
|
-
this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
|
|
2358
|
-
particlesOptions.load(overrideOptions);
|
|
2359
|
-
const effectData = this.effectData, shapeData = this.shapeData;
|
|
2360
|
-
if (effectData) {
|
|
2361
|
-
particlesOptions.load(effectData.particles);
|
|
2362
|
-
}
|
|
2363
|
-
if (shapeData) {
|
|
2364
|
-
particlesOptions.load(shapeData.particles);
|
|
2365
|
-
}
|
|
2366
|
-
this.effectClose = effectData?.close ?? particlesOptions.effect.close;
|
|
2367
|
-
this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
|
|
2368
|
-
this.options = particlesOptions;
|
|
2059
|
+
initParticleState(this, id, group);
|
|
2060
|
+
this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
|
|
2369
2061
|
container.retina.initParticle(this);
|
|
2370
|
-
|
|
2371
|
-
updater.preInit?.(this);
|
|
2372
|
-
}
|
|
2062
|
+
runUpdaterPreInit(container.particleUpdaters, this);
|
|
2373
2063
|
this.bubble = {
|
|
2374
2064
|
inRange: false,
|
|
2375
2065
|
};
|
|
@@ -2382,32 +2072,11 @@ class Particle {
|
|
|
2382
2072
|
this.velocity = this.initialVelocity.copy();
|
|
2383
2073
|
this.zIndexFactor = this.position.z / container.zLayers;
|
|
2384
2074
|
this.sides = 24;
|
|
2385
|
-
|
|
2386
|
-
if (this.effect) {
|
|
2387
|
-
effectDrawer = container.effectDrawers.get(this.effect);
|
|
2388
|
-
}
|
|
2389
|
-
if (effectDrawer?.loadEffect) {
|
|
2390
|
-
effectDrawer.loadEffect(this);
|
|
2391
|
-
}
|
|
2392
|
-
if (this.shape) {
|
|
2393
|
-
shapeDrawer = container.shapeDrawers.get(this.shape);
|
|
2394
|
-
}
|
|
2395
|
-
if (shapeDrawer?.loadShape) {
|
|
2396
|
-
shapeDrawer.loadShape(this);
|
|
2397
|
-
}
|
|
2398
|
-
const sideCountFunc = shapeDrawer?.getSidesCount;
|
|
2399
|
-
if (sideCountFunc) {
|
|
2400
|
-
this.sides = sideCountFunc(this);
|
|
2401
|
-
}
|
|
2075
|
+
initParticleDrawers(this, container);
|
|
2402
2076
|
this.spawning = false;
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
effectDrawer?.particleInit?.(container, this);
|
|
2407
|
-
shapeDrawer?.particleInit?.(container, this);
|
|
2408
|
-
for (const plugin of container.particleCreatedPlugins) {
|
|
2409
|
-
plugin.particleCreated?.(this);
|
|
2410
|
-
}
|
|
2077
|
+
runUpdaterInit(container.particleUpdaters, this);
|
|
2078
|
+
runDrawerInit(container, this);
|
|
2079
|
+
runParticleCreatedPlugins(container, this);
|
|
2411
2080
|
}
|
|
2412
2081
|
isInsideCanvas(direction) {
|
|
2413
2082
|
return this.#getInsideCanvasResult({ direction }).inside;
|
|
@@ -2421,15 +2090,15 @@ class Particle {
|
|
|
2421
2090
|
}
|
|
2422
2091
|
const angle = this.roll.angle;
|
|
2423
2092
|
if (this.roll.horizontal && this.roll.vertical) {
|
|
2424
|
-
const
|
|
2093
|
+
const adjustedAngle = normalizeAngle(angle, doublePI);
|
|
2425
2094
|
return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
|
|
2426
2095
|
}
|
|
2427
2096
|
if (this.roll.horizontal) {
|
|
2428
|
-
const
|
|
2097
|
+
const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
|
|
2429
2098
|
return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
|
|
2430
2099
|
}
|
|
2431
2100
|
if (this.roll.vertical) {
|
|
2432
|
-
const
|
|
2101
|
+
const adjustedAngle = normalizeAngle(angle, doublePI);
|
|
2433
2102
|
return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
|
|
2434
2103
|
}
|
|
2435
2104
|
return false;
|
|
@@ -2442,10 +2111,10 @@ class Particle {
|
|
|
2442
2111
|
updater.reset?.(this);
|
|
2443
2112
|
}
|
|
2444
2113
|
}
|
|
2445
|
-
#calcPosition
|
|
2114
|
+
#calcPosition(position, zIndex) {
|
|
2446
2115
|
let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
|
|
2447
|
-
const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size
|
|
2448
|
-
|
|
2116
|
+
const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
|
|
2117
|
+
for (;;) {
|
|
2449
2118
|
for (const plugin of plugins) {
|
|
2450
2119
|
const pluginPos = plugin.particlePosition?.(posVec, this);
|
|
2451
2120
|
if (pluginPos) {
|
|
@@ -2473,9 +2142,8 @@ class Particle {
|
|
|
2473
2142
|
tryCount += tryCountIncrement;
|
|
2474
2143
|
posVec = undefined;
|
|
2475
2144
|
}
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
#calculateVelocity = () => {
|
|
2145
|
+
}
|
|
2146
|
+
#calculateVelocity() {
|
|
2479
2147
|
const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
|
|
2480
2148
|
if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
|
|
2481
2149
|
return res;
|
|
@@ -2491,8 +2159,8 @@ class Particle {
|
|
|
2491
2159
|
res.length *= getRandom();
|
|
2492
2160
|
}
|
|
2493
2161
|
return res;
|
|
2494
|
-
}
|
|
2495
|
-
#fixHorizontal
|
|
2162
|
+
}
|
|
2163
|
+
#fixHorizontal(pos, radius, outMode) {
|
|
2496
2164
|
fixOutMode({
|
|
2497
2165
|
outMode,
|
|
2498
2166
|
checkModes: [OutMode.bounce],
|
|
@@ -2501,8 +2169,8 @@ class Particle {
|
|
|
2501
2169
|
setCb: (value) => (pos.x += value),
|
|
2502
2170
|
radius,
|
|
2503
2171
|
});
|
|
2504
|
-
}
|
|
2505
|
-
#fixVertical
|
|
2172
|
+
}
|
|
2173
|
+
#fixVertical(pos, radius, outMode) {
|
|
2506
2174
|
fixOutMode({
|
|
2507
2175
|
outMode,
|
|
2508
2176
|
checkModes: [OutMode.bounce],
|
|
@@ -2511,8 +2179,8 @@ class Particle {
|
|
|
2511
2179
|
setCb: (value) => (pos.y += value),
|
|
2512
2180
|
radius,
|
|
2513
2181
|
});
|
|
2514
|
-
}
|
|
2515
|
-
#getDefaultInsideCanvasResult
|
|
2182
|
+
}
|
|
2183
|
+
#getDefaultInsideCanvasResult(direction, outMode) {
|
|
2516
2184
|
const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
|
|
2517
2185
|
if (direction === OutModeDirection.bottom) {
|
|
2518
2186
|
return {
|
|
@@ -2545,8 +2213,8 @@ class Particle {
|
|
|
2545
2213
|
position.x <= canvasSize.width + radius,
|
|
2546
2214
|
reason: "default",
|
|
2547
2215
|
};
|
|
2548
|
-
}
|
|
2549
|
-
#getInsideCanvasCallbackData
|
|
2216
|
+
}
|
|
2217
|
+
#getInsideCanvasCallbackData(direction, outMode) {
|
|
2550
2218
|
return {
|
|
2551
2219
|
canvasSize: this.#container.canvas.size,
|
|
2552
2220
|
direction,
|
|
@@ -2554,8 +2222,8 @@ class Particle {
|
|
|
2554
2222
|
particle: this,
|
|
2555
2223
|
radius: this.getRadius(),
|
|
2556
2224
|
};
|
|
2557
|
-
}
|
|
2558
|
-
#getInsideCanvasResult
|
|
2225
|
+
}
|
|
2226
|
+
#getInsideCanvasResult(data) {
|
|
2559
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;
|
|
2560
2228
|
if (!shapeCheck && !effectCheck) {
|
|
2561
2229
|
return defaultResult;
|
|
@@ -2570,8 +2238,8 @@ class Particle {
|
|
|
2570
2238
|
};
|
|
2571
2239
|
}
|
|
2572
2240
|
return shapeResult ?? effectResult ?? defaultResult;
|
|
2573
|
-
}
|
|
2574
|
-
#getRollColor
|
|
2241
|
+
}
|
|
2242
|
+
#getRollColor(color) {
|
|
2575
2243
|
if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
|
|
2576
2244
|
return color;
|
|
2577
2245
|
}
|
|
@@ -2585,8 +2253,8 @@ class Particle {
|
|
|
2585
2253
|
return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
|
|
2586
2254
|
}
|
|
2587
2255
|
return color;
|
|
2588
|
-
}
|
|
2589
|
-
#initPosition
|
|
2256
|
+
}
|
|
2257
|
+
#initPosition(position) {
|
|
2590
2258
|
const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
|
|
2591
2259
|
if (!initialPosition) {
|
|
2592
2260
|
throw new Error("a valid position cannot be found for particle");
|
|
@@ -2609,8 +2277,8 @@ class Particle {
|
|
|
2609
2277
|
break;
|
|
2610
2278
|
}
|
|
2611
2279
|
this.offset = Vector.origin;
|
|
2612
|
-
}
|
|
2613
|
-
#normalizeInsideCanvasResult
|
|
2280
|
+
}
|
|
2281
|
+
#normalizeInsideCanvasResult(result, reason) {
|
|
2614
2282
|
if (typeof result === "boolean") {
|
|
2615
2283
|
return {
|
|
2616
2284
|
inside: result,
|
|
@@ -2622,7 +2290,7 @@ class Particle {
|
|
|
2622
2290
|
margin: result.margin,
|
|
2623
2291
|
reason: result.reason ?? reason,
|
|
2624
2292
|
};
|
|
2625
|
-
}
|
|
2293
|
+
}
|
|
2626
2294
|
}
|
|
2627
2295
|
|
|
2628
2296
|
class SpatialHashGrid {
|
|
@@ -2975,10 +2643,10 @@ class ParticlesManager {
|
|
|
2975
2643
|
}
|
|
2976
2644
|
this.#resizeFactor = undefined;
|
|
2977
2645
|
}
|
|
2978
|
-
#addToPool
|
|
2646
|
+
#addToPool(...particles) {
|
|
2979
2647
|
this.#pool.push(...particles);
|
|
2980
|
-
}
|
|
2981
|
-
#applyDensity
|
|
2648
|
+
}
|
|
2649
|
+
#applyDensity(options, pluginsCount, group, groupOptions) {
|
|
2982
2650
|
const numberOptions = options.number;
|
|
2983
2651
|
if (!numberOptions.density.enable) {
|
|
2984
2652
|
if (group === undefined) {
|
|
@@ -3002,36 +2670,19 @@ class ParticlesManager {
|
|
|
3002
2670
|
else if (particlesCount > particlesNumber) {
|
|
3003
2671
|
this.removeQuantity(particlesCount - particlesNumber, group);
|
|
3004
2672
|
}
|
|
3005
|
-
}
|
|
3006
|
-
#createBuckets
|
|
2673
|
+
}
|
|
2674
|
+
#createBuckets(zLayers) {
|
|
3007
2675
|
const bucketCount = Math.max(Math.floor(zLayers), one);
|
|
3008
2676
|
return Array.from({ length: bucketCount }, () => []);
|
|
3009
|
-
}
|
|
3010
|
-
#getBucketIndex
|
|
2677
|
+
}
|
|
2678
|
+
#getBucketIndex(zIndex) {
|
|
3011
2679
|
const maxBucketIndex = this.#zBuckets.length - one;
|
|
3012
2680
|
if (maxBucketIndex <= minIndex) {
|
|
3013
2681
|
return minIndex;
|
|
3014
2682
|
}
|
|
3015
2683
|
return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
|
|
3016
|
-
}
|
|
3017
|
-
#
|
|
3018
|
-
let start = minIndex, end = bucket.length;
|
|
3019
|
-
while (start < end) {
|
|
3020
|
-
const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
|
|
3021
|
-
if (!middleParticle) {
|
|
3022
|
-
end = middle;
|
|
3023
|
-
continue;
|
|
3024
|
-
}
|
|
3025
|
-
if (middleParticle.id < particleId) {
|
|
3026
|
-
start = middle + one;
|
|
3027
|
-
}
|
|
3028
|
-
else {
|
|
3029
|
-
end = middle;
|
|
3030
|
-
}
|
|
3031
|
-
}
|
|
3032
|
-
return start;
|
|
3033
|
-
};
|
|
3034
|
-
#initDensityFactor = densityOptions => {
|
|
2684
|
+
}
|
|
2685
|
+
#initDensityFactor(densityOptions) {
|
|
3035
2686
|
const container = this.#container;
|
|
3036
2687
|
if (!densityOptions.enable) {
|
|
3037
2688
|
return defaultDensityFactor;
|
|
@@ -3041,16 +2692,16 @@ class ParticlesManager {
|
|
|
3041
2692
|
return defaultDensityFactor;
|
|
3042
2693
|
}
|
|
3043
2694
|
return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
|
|
3044
|
-
}
|
|
3045
|
-
#insertParticleIntoBucket
|
|
2695
|
+
}
|
|
2696
|
+
#insertParticleIntoBucket(particle) {
|
|
3046
2697
|
const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
|
|
3047
2698
|
if (!bucket) {
|
|
3048
2699
|
return;
|
|
3049
2700
|
}
|
|
3050
|
-
bucket.
|
|
2701
|
+
bucket.push(particle);
|
|
3051
2702
|
this.#particleBuckets.set(particle.id, bucketIndex);
|
|
3052
|
-
}
|
|
3053
|
-
#removeParticle
|
|
2703
|
+
}
|
|
2704
|
+
#removeParticle(index, group, override) {
|
|
3054
2705
|
const particle = this.#array[index];
|
|
3055
2706
|
if (!particle) {
|
|
3056
2707
|
return false;
|
|
@@ -3066,22 +2717,20 @@ class ParticlesManager {
|
|
|
3066
2717
|
});
|
|
3067
2718
|
this.#addToPool(particle);
|
|
3068
2719
|
return true;
|
|
3069
|
-
}
|
|
3070
|
-
#removeParticleFromBucket
|
|
2720
|
+
}
|
|
2721
|
+
#removeParticleFromBucket(particle) {
|
|
3071
2722
|
const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
|
|
3072
2723
|
if (!bucket) {
|
|
3073
2724
|
this.#particleBuckets.delete(particle.id);
|
|
3074
2725
|
return;
|
|
3075
2726
|
}
|
|
3076
|
-
const
|
|
3077
|
-
if (
|
|
3078
|
-
|
|
3079
|
-
return;
|
|
2727
|
+
const idx = bucket.findIndex(p => p.id === particle.id);
|
|
2728
|
+
if (idx >= minIndex) {
|
|
2729
|
+
bucket.splice(idx, deleteCount);
|
|
3080
2730
|
}
|
|
3081
|
-
bucket.splice(particleIndex, deleteCount);
|
|
3082
2731
|
this.#particleBuckets.delete(particle.id);
|
|
3083
|
-
}
|
|
3084
|
-
#resetBuckets
|
|
2732
|
+
}
|
|
2733
|
+
#resetBuckets(zLayers) {
|
|
3085
2734
|
const bucketCount = Math.max(Math.floor(zLayers), one);
|
|
3086
2735
|
if (this.#zBuckets.length !== bucketCount) {
|
|
3087
2736
|
this.#zBuckets = this.#createBuckets(bucketCount);
|
|
@@ -3090,8 +2739,8 @@ class ParticlesManager {
|
|
|
3090
2739
|
for (const bucket of this.#zBuckets) {
|
|
3091
2740
|
bucket.length = minIndex;
|
|
3092
2741
|
}
|
|
3093
|
-
}
|
|
3094
|
-
#updateParticleBucket
|
|
2742
|
+
}
|
|
2743
|
+
#updateParticleBucket(particle) {
|
|
3095
2744
|
const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
|
|
3096
2745
|
if (currentBucketIndex === undefined) {
|
|
3097
2746
|
this.#insertParticleIntoBucket(particle);
|
|
@@ -3102,9 +2751,9 @@ class ParticlesManager {
|
|
|
3102
2751
|
}
|
|
3103
2752
|
const currentBucket = this.#zBuckets[currentBucketIndex];
|
|
3104
2753
|
if (currentBucket) {
|
|
3105
|
-
const
|
|
3106
|
-
if (
|
|
3107
|
-
currentBucket.splice(
|
|
2754
|
+
const idx = currentBucket.findIndex(p => p.id === particle.id);
|
|
2755
|
+
if (idx >= minIndex) {
|
|
2756
|
+
currentBucket.splice(idx, deleteCount);
|
|
3108
2757
|
}
|
|
3109
2758
|
}
|
|
3110
2759
|
const newBucket = this.#zBuckets[newBucketIndex];
|
|
@@ -3112,10 +2761,16 @@ class ParticlesManager {
|
|
|
3112
2761
|
this.#particleBuckets.set(particle.id, newBucketIndex);
|
|
3113
2762
|
return;
|
|
3114
2763
|
}
|
|
3115
|
-
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
|
+
}
|
|
3116
2771
|
this.#particleBuckets.set(particle.id, newBucketIndex);
|
|
3117
|
-
}
|
|
3118
|
-
#updateParticlesPhase1
|
|
2772
|
+
}
|
|
2773
|
+
#updateParticlesPhase1(delta) {
|
|
3119
2774
|
const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
|
|
3120
2775
|
for (const particle of this.#array) {
|
|
3121
2776
|
if (resizeFactor && !particle.ignoresResizeRatio) {
|
|
@@ -3141,8 +2796,8 @@ class ParticlesManager {
|
|
|
3141
2796
|
this.grid.insert(particle);
|
|
3142
2797
|
}
|
|
3143
2798
|
return particlesToDelete;
|
|
3144
|
-
}
|
|
3145
|
-
#updateParticlesPhase2
|
|
2799
|
+
}
|
|
2800
|
+
#updateParticlesPhase2(delta, particlesToDelete) {
|
|
3146
2801
|
for (const particle of this.#array) {
|
|
3147
2802
|
if (particle.destroyed) {
|
|
3148
2803
|
particlesToDelete.add(particle);
|
|
@@ -3158,7 +2813,7 @@ class ParticlesManager {
|
|
|
3158
2813
|
}
|
|
3159
2814
|
this.#updateParticleBucket(particle);
|
|
3160
2815
|
}
|
|
3161
|
-
}
|
|
2816
|
+
}
|
|
3162
2817
|
}
|
|
3163
2818
|
|
|
3164
2819
|
class Retina {
|
|
@@ -3520,7 +3175,7 @@ class Container {
|
|
|
3520
3175
|
}
|
|
3521
3176
|
return refresh;
|
|
3522
3177
|
}
|
|
3523
|
-
#nextFrame
|
|
3178
|
+
#nextFrame(timestamp) {
|
|
3524
3179
|
try {
|
|
3525
3180
|
if (!this.#smooth &&
|
|
3526
3181
|
this.#lastFrameTime !== undefined &&
|
|
@@ -3548,7 +3203,7 @@ class Container {
|
|
|
3548
3203
|
catch (e) {
|
|
3549
3204
|
getLogger().error("error in animation loop", e);
|
|
3550
3205
|
}
|
|
3551
|
-
}
|
|
3206
|
+
}
|
|
3552
3207
|
}
|
|
3553
3208
|
|
|
3554
3209
|
export { Container };
|