@tsparticles/engine 4.0.0-alpha.2 → 4.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/638.min.js +1 -1
  2. package/638.min.js.LICENSE.txt +1 -1
  3. package/browser/Core/Canvas.js +15 -19
  4. package/browser/Core/Container.js +10 -15
  5. package/browser/Core/Engine.js +34 -14
  6. package/browser/Core/Interfaces/IParticleOpacityData.js +1 -0
  7. package/browser/Core/Interfaces/IParticleRotateData.js +1 -0
  8. package/browser/Core/Particle.js +95 -49
  9. package/browser/Utils/CanvasUtils.js +26 -83
  10. package/browser/Utils/ColorUtils.js +15 -2
  11. package/browser/Utils/MathUtils.js +3 -2
  12. package/browser/Utils/Utils.js +1 -1
  13. package/cjs/Core/Canvas.js +15 -19
  14. package/cjs/Core/Container.js +10 -15
  15. package/cjs/Core/Engine.js +34 -14
  16. package/cjs/Core/Interfaces/IParticleOpacityData.js +1 -0
  17. package/cjs/Core/Interfaces/IParticleRotateData.js +1 -0
  18. package/cjs/Core/Particle.js +95 -49
  19. package/cjs/Utils/CanvasUtils.js +26 -83
  20. package/cjs/Utils/ColorUtils.js +15 -2
  21. package/cjs/Utils/MathUtils.js +3 -2
  22. package/cjs/Utils/Utils.js +1 -1
  23. package/dist_browser_Core_Container_js.js +4 -4
  24. package/esm/Core/Canvas.js +15 -19
  25. package/esm/Core/Container.js +10 -15
  26. package/esm/Core/Engine.js +34 -14
  27. package/esm/Core/Interfaces/IParticleOpacityData.js +1 -0
  28. package/esm/Core/Interfaces/IParticleRotateData.js +1 -0
  29. package/esm/Core/Particle.js +95 -49
  30. package/esm/Utils/CanvasUtils.js +26 -83
  31. package/esm/Utils/ColorUtils.js +15 -2
  32. package/esm/Utils/MathUtils.js +3 -2
  33. package/esm/Utils/Utils.js +1 -1
  34. package/package.json +1 -1
  35. package/report.html +1 -1
  36. package/tsparticles.engine.js +6 -6
  37. package/tsparticles.engine.min.js +1 -1
  38. package/tsparticles.engine.min.js.LICENSE.txt +1 -1
  39. package/types/Core/Canvas.d.ts +3 -0
  40. package/types/Core/Container.d.ts +1 -0
  41. package/types/Core/Engine.d.ts +1 -1
  42. package/types/Core/Interfaces/IDrawParticleParams.d.ts +1 -1
  43. package/types/Core/Interfaces/IParticleOpacityData.d.ts +4 -0
  44. package/types/Core/Interfaces/IParticleRotateData.d.ts +4 -0
  45. package/types/Core/Interfaces/IParticleTransformValues.d.ts +4 -4
  46. package/types/Core/Interfaces/IParticleUpdater.d.ts +1 -1
  47. package/types/Core/Particle.d.ts +12 -0
  48. package/types/Types/CustomEventListener.d.ts +1 -1
  49. package/types/Utils/CanvasUtils.d.ts +6 -21
  50. package/types/Utils/EventDispatcher.d.ts +1 -1
  51. package/umd/Core/Canvas.js +14 -18
  52. package/umd/Core/Container.js +10 -15
  53. package/umd/Core/Engine.js +34 -14
  54. package/umd/Core/Interfaces/IParticleOpacityData.js +12 -0
  55. package/umd/Core/Interfaces/IParticleRotateData.js +12 -0
  56. package/umd/Core/Particle.js +94 -48
  57. package/umd/Utils/CanvasUtils.js +25 -82
  58. package/umd/Utils/ColorUtils.js +15 -2
  59. package/umd/Utils/MathUtils.js +3 -2
  60. package/umd/Utils/Utils.js +1 -1
@@ -50,6 +50,7 @@ var __importStar = (this && this.__importStar) || (function () {
50
50
  const EventType_js_1 = require("../Enums/Types/EventType.js");
51
51
  const LogUtils_js_1 = require("../Utils/LogUtils.js");
52
52
  const MathUtils_js_1 = require("../Utils/MathUtils.js");
53
+ const fullPercent = "100%";
53
54
  async function getItemsFromInitializer(container, map, initializers, force = false) {
54
55
  let res = map.get(container);
55
56
  if (!res || force) {
@@ -71,6 +72,7 @@ var __importStar = (this && this.__importStar) || (function () {
71
72
  return data.fallback;
72
73
  }
73
74
  const getCanvasFromContainer = (domContainer) => {
75
+ const documentSafe = (0, Utils_js_1.safeDocument)();
74
76
  let canvasEl;
75
77
  if (domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === Constants_js_1.canvasTag) {
76
78
  canvasEl = domContainer;
@@ -83,28 +85,24 @@ var __importStar = (this && this.__importStar) || (function () {
83
85
  canvasEl.dataset[Constants_js_1.generatedAttribute] = Constants_js_1.generatedFalse;
84
86
  }
85
87
  else {
86
- canvasEl = (0, Utils_js_1.safeDocument)().createElement(Constants_js_1.canvasTag);
88
+ canvasEl = documentSafe.createElement(Constants_js_1.canvasTag);
87
89
  canvasEl.dataset[Constants_js_1.generatedAttribute] = Constants_js_1.generatedTrue;
88
90
  domContainer.appendChild(canvasEl);
89
91
  }
90
92
  }
91
- const fullPercent = "100%";
92
- if (!canvasEl.style.width) {
93
- canvasEl.style.width = fullPercent;
94
- }
95
- if (!canvasEl.style.height) {
96
- canvasEl.style.height = fullPercent;
97
- }
93
+ canvasEl.style.width ||= fullPercent;
94
+ canvasEl.style.height ||= fullPercent;
98
95
  return canvasEl;
99
96
  }, getDomContainer = (id, source) => {
100
- let domContainer = source ?? (0, Utils_js_1.safeDocument)().getElementById(id);
97
+ const documentSafe = (0, Utils_js_1.safeDocument)();
98
+ let domContainer = source ?? document.getElementById(id);
101
99
  if (domContainer) {
102
100
  return domContainer;
103
101
  }
104
- domContainer = (0, Utils_js_1.safeDocument)().createElement("div");
102
+ domContainer = documentSafe.createElement("div");
105
103
  domContainer.id = id;
106
104
  domContainer.dataset[Constants_js_1.generatedAttribute] = Constants_js_1.generatedTrue;
107
- (0, Utils_js_1.safeDocument)().body.append(domContainer);
105
+ documentSafe.body.append(domContainer);
108
106
  return domContainer;
109
107
  };
110
108
  class Engine {
@@ -141,7 +139,7 @@ var __importStar = (this && this.__importStar) || (function () {
141
139
  return this._domArray;
142
140
  }
143
141
  get version() {
144
- return "4.0.0-alpha.2";
142
+ return "4.0.0-alpha.3";
145
143
  }
146
144
  addColorManager(manager) {
147
145
  this.colorManagers.set(manager.key, manager);
@@ -267,10 +265,32 @@ var __importStar = (this && this.__importStar) || (function () {
267
265
  if (this._initialized) {
268
266
  return;
269
267
  }
270
- for (const loadPromise of this._loadPromises) {
271
- await loadPromise(this);
268
+ const executed = new Set(), allLoaders = new Set(this._loadPromises), stack = [...allLoaders];
269
+ while (stack.length) {
270
+ const loader = stack.shift();
271
+ if (!loader) {
272
+ continue;
273
+ }
274
+ if (executed.has(loader)) {
275
+ continue;
276
+ }
277
+ executed.add(loader);
278
+ const inner = [], origRegister = this.register.bind(this);
279
+ this.register = (...loaders) => {
280
+ inner.push(...loaders);
281
+ for (const loader of loaders) {
282
+ allLoaders.add(loader);
283
+ }
284
+ };
285
+ await loader(this);
286
+ this.register = origRegister;
287
+ stack.unshift(...inner);
288
+ this._loadPromises.delete(loader);
272
289
  }
273
290
  this._loadPromises.clear();
291
+ for (const loader of allLoaders) {
292
+ this._loadPromises.add(loader);
293
+ }
274
294
  this._initialized = true;
275
295
  }
276
296
  item(index) {
@@ -0,0 +1,12 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ });
@@ -0,0 +1,12 @@
1
+ (function (factory) {
2
+ if (typeof module === "object" && typeof module.exports === "object") {
3
+ var v = factory(require, exports);
4
+ if (v !== undefined) module.exports = v;
5
+ }
6
+ else if (typeof define === "function" && define.amd) {
7
+ define(["require", "exports"], factory);
8
+ }
9
+ })(function (require, exports) {
10
+ "use strict";
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ });
@@ -51,51 +51,50 @@
51
51
  class Particle {
52
52
  constructor(engine, container) {
53
53
  this.container = container;
54
- this._calcPosition = (container, position, zIndex, tryCount = Constants_js_1.defaultRetryCount) => {
55
- const plugins = container.plugins.values();
56
- for (const plugin of plugins) {
57
- const pluginPos = plugin.particlePosition?.(position, this);
58
- if (pluginPos) {
59
- return Vectors_js_1.Vector3d.create(pluginPos.x, pluginPos.y, zIndex);
54
+ this._cachedOpacityData = {
55
+ opacity: Constants_js_1.defaultOpacity,
56
+ strokeOpacity: Constants_js_1.defaultOpacity,
57
+ };
58
+ this._cachedPosition = Vectors_js_1.Vector3d.origin;
59
+ this._cachedRotateData = { sin: 0, cos: 0 };
60
+ this._cachedTransform = {
61
+ a: 1,
62
+ b: 0,
63
+ c: 0,
64
+ d: 1,
65
+ };
66
+ this._calcPosition = (position, zIndex) => {
67
+ let tryCount = Constants_js_1.defaultRetryCount, posVec = position ? Vectors_js_1.Vector3d.create(position.x, position.y, zIndex) : undefined;
68
+ const container = this.container, plugins = Array.from(container.plugins.values()), outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
69
+ while (!signal.aborted) {
70
+ for (const plugin of plugins) {
71
+ const pluginPos = plugin.particlePosition?.(posVec, this);
72
+ if (pluginPos) {
73
+ return Vectors_js_1.Vector3d.create(pluginPos.x, pluginPos.y, zIndex);
74
+ }
60
75
  }
61
- }
62
- const canvasSize = container.canvas.size, exactPosition = (0, MathUtils_js_1.calcExactPositionOrRandomFromSize)({
63
- size: canvasSize,
64
- position: position,
65
- }), pos = Vectors_js_1.Vector3d.create(exactPosition.x, exactPosition.y, zIndex), radius = this.getRadius(), outModes = this.options.move.outModes, fixHorizontal = (outMode) => {
66
- fixOutMode({
67
- outMode,
68
- checkModes: [OutMode_js_1.OutMode.bounce],
69
- coord: pos.x,
70
- maxCoord: container.canvas.size.width,
71
- setCb: (value) => (pos.x += value),
72
- radius,
73
- });
74
- }, fixVertical = (outMode) => {
75
- fixOutMode({
76
- outMode,
77
- checkModes: [OutMode_js_1.OutMode.bounce],
78
- coord: pos.y,
79
- maxCoord: container.canvas.size.height,
80
- setCb: (value) => (pos.y += value),
81
- radius,
82
- });
83
- };
84
- fixHorizontal(outModes.left ?? outModes.default);
85
- fixHorizontal(outModes.right ?? outModes.default);
86
- fixVertical(outModes.top ?? outModes.default);
87
- fixVertical(outModes.bottom ?? outModes.default);
88
- let isValidPosition = true;
89
- for (const plugin of plugins) {
90
- isValidPosition = plugin.checkParticlePosition?.(this, pos, tryCount);
91
- if (isValidPosition === false) {
92
- break;
76
+ const exactPosition = (0, MathUtils_js_1.calcExactPositionOrRandomFromSize)({
77
+ size: canvasSize,
78
+ position: posVec,
79
+ }), pos = Vectors_js_1.Vector3d.create(exactPosition.x, exactPosition.y, zIndex);
80
+ this._fixHorizontal(pos, radius, outModes.left ?? outModes.default);
81
+ this._fixHorizontal(pos, radius, outModes.right ?? outModes.default);
82
+ this._fixVertical(pos, radius, outModes.top ?? outModes.default);
83
+ this._fixVertical(pos, radius, outModes.bottom ?? outModes.default);
84
+ let isValidPosition = true;
85
+ for (const plugin of plugins) {
86
+ isValidPosition = plugin.checkParticlePosition?.(this, pos, tryCount) ?? true;
87
+ if (!isValidPosition) {
88
+ break;
89
+ }
93
90
  }
91
+ if (isValidPosition) {
92
+ return pos;
93
+ }
94
+ tryCount += Constants_js_1.tryCountIncrement;
95
+ posVec = undefined;
94
96
  }
95
- if (!isValidPosition) {
96
- return this._calcPosition(container, undefined, zIndex, tryCount + Constants_js_1.tryCountIncrement);
97
- }
98
- return pos;
97
+ return posVec;
99
98
  };
100
99
  this._calculateVelocity = () => {
101
100
  const baseVelocity = (0, MathUtils_js_1.getParticleBaseVelocity)(this.direction), res = baseVelocity.copy(), moveOptions = this.options.move;
@@ -114,6 +113,26 @@
114
113
  }
115
114
  return res;
116
115
  };
116
+ this._fixHorizontal = (pos, radius, outMode) => {
117
+ fixOutMode({
118
+ outMode,
119
+ checkModes: [OutMode_js_1.OutMode.bounce],
120
+ coord: pos.x,
121
+ maxCoord: this.container.canvas.size.width,
122
+ setCb: (value) => (pos.x += value),
123
+ radius,
124
+ });
125
+ };
126
+ this._fixVertical = (pos, radius, outMode) => {
127
+ fixOutMode({
128
+ outMode,
129
+ checkModes: [OutMode_js_1.OutMode.bounce],
130
+ coord: pos.y,
131
+ maxCoord: this.container.canvas.size.height,
132
+ setCb: (value) => (pos.y += value),
133
+ radius,
134
+ });
135
+ };
117
136
  this._getRollColor = color => {
118
137
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
119
138
  return color;
@@ -132,7 +151,11 @@
132
151
  };
133
152
  this._initPosition = position => {
134
153
  const container = this.container, zIndexValue = (0, MathUtils_js_1.getRangeValue)(this.options.zIndex.value);
135
- this.position = this._calcPosition(container, position, (0, MathUtils_js_1.clamp)(zIndexValue, Constants_js_1.minZ, container.zLayers));
154
+ const initialPosition = this._calcPosition(position, (0, MathUtils_js_1.clamp)(zIndexValue, Constants_js_1.minZ, container.zLayers));
155
+ if (!initialPosition) {
156
+ throw new Error("a valid position cannot be found for particle");
157
+ }
158
+ this.position = initialPosition;
136
159
  this.initialPosition = this.position.copy();
137
160
  const canvasSize = container.canvas.size;
138
161
  this.moveCenter = {
@@ -192,19 +215,42 @@
192
215
  getMass() {
193
216
  return this.getRadius() ** Constants_js_1.squareExp * Math.PI * Constants_js_1.half;
194
217
  }
218
+ getOpacity() {
219
+ const zIndexOptions = this.options.zIndex, zIndexFactor = Constants_js_1.zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = this.bubble.opacity ?? (0, MathUtils_js_1.getRangeValue)(this.opacity?.value ?? Constants_js_1.defaultOpacity), strokeOpacity = this.strokeOpacity ?? opacity;
220
+ this._cachedOpacityData.opacity = opacity * zOpacityFactor;
221
+ this._cachedOpacityData.strokeOpacity = strokeOpacity * zOpacityFactor;
222
+ return this._cachedOpacityData;
223
+ }
195
224
  getPosition() {
196
- return {
197
- x: this.position.x + this.offset.x,
198
- y: this.position.y + this.offset.y,
199
- z: this.position.z,
200
- };
225
+ this._cachedPosition.x = this.position.x + this.offset.x;
226
+ this._cachedPosition.y = this.position.y + this.offset.y;
227
+ this._cachedPosition.z = this.position.z;
228
+ return this._cachedPosition;
201
229
  }
202
230
  getRadius() {
203
231
  return this.bubble.radius ?? this.size.value;
204
232
  }
233
+ getRotateData() {
234
+ const angle = this.getAngle();
235
+ this._cachedRotateData.sin = Math.sin(angle);
236
+ this._cachedRotateData.cos = Math.cos(angle);
237
+ return this._cachedRotateData;
238
+ }
205
239
  getStrokeColor() {
206
240
  return this._getRollColor(this.bubble.color ?? (0, ColorUtils_js_1.getHslFromAnimation)(this.strokeColor));
207
241
  }
242
+ getTransformData(externalTransform) {
243
+ const rotateData = this.getRotateData(), rotating = this.isRotating;
244
+ this._cachedTransform.a = rotateData.cos * (externalTransform.a ?? Constants_js_1.defaultTransform.a);
245
+ this._cachedTransform.b = rotating
246
+ ? rotateData.sin * (externalTransform.b ?? Constants_js_1.identity)
247
+ : (externalTransform.b ?? Constants_js_1.defaultTransform.b);
248
+ this._cachedTransform.c = rotating
249
+ ? -rotateData.sin * (externalTransform.c ?? Constants_js_1.identity)
250
+ : (externalTransform.c ?? Constants_js_1.defaultTransform.c);
251
+ this._cachedTransform.d = rotateData.cos * (externalTransform.d ?? Constants_js_1.defaultTransform.d);
252
+ return this._cachedTransform;
253
+ }
208
254
  init(id, position, overrideOptions, group) {
209
255
  const container = this.container, engine = this._engine;
210
256
  this.id = id;
@@ -53,15 +53,7 @@
53
53
  context.clearRect(Constants_js_1.originPoint.x, Constants_js_1.originPoint.y, dimension.width, dimension.height);
54
54
  }
55
55
  function drawParticle(data) {
56
- const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, pos = particle.getPosition(), angle = particle.getAngle(), rotateData = {
57
- sin: Math.sin(angle),
58
- cos: Math.cos(angle),
59
- }, rotating = particle.isRotating, transformData = {
60
- a: rotateData.cos * (transform.a ?? Constants_js_1.defaultTransform.a),
61
- b: rotating ? rotateData.sin * (transform.b ?? Constants_js_1.identity) : (transform.b ?? Constants_js_1.defaultTransform.b),
62
- c: rotating ? -rotateData.sin * (transform.c ?? Constants_js_1.identity) : (transform.c ?? Constants_js_1.defaultTransform.c),
63
- d: rotateData.cos * (transform.d ?? Constants_js_1.defaultTransform.d),
64
- };
56
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, pos = particle.getPosition(), transformData = particle.getTransformData(transform);
65
57
  context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
66
58
  if (colorStyles.fill) {
67
59
  context.fillStyle = colorStyles.fill;
@@ -72,24 +64,25 @@
72
64
  context.strokeStyle = colorStyles.stroke;
73
65
  }
74
66
  const drawData = {
75
- container,
76
67
  context,
77
68
  particle,
78
69
  radius,
79
70
  opacity,
80
71
  delta,
72
+ pixelRatio: container.retina.pixelRatio,
73
+ fill: particle.shapeFill,
74
+ stroke: strokeWidth > Constants_js_1.minStrokeWidth || !particle.shapeFill,
81
75
  transformData,
82
- strokeWidth,
83
76
  };
84
- drawBeforeEffect(drawData);
85
- drawShapeBeforeDraw(drawData);
86
- drawShape(drawData);
87
- drawShapeAfterDraw(drawData);
88
- drawAfterEffect(drawData);
77
+ drawBeforeEffect(container, drawData);
78
+ drawShapeBeforeDraw(container, drawData);
79
+ drawShape(container, drawData);
80
+ drawShapeAfterDraw(container, drawData);
81
+ drawAfterEffect(container, drawData);
89
82
  context.resetTransform();
90
83
  }
91
- function drawAfterEffect(data) {
92
- const { container, context, particle, radius, opacity, strokeWidth, delta, transformData } = data;
84
+ function drawAfterEffect(container, data) {
85
+ const { particle } = data;
93
86
  if (!particle.effect) {
94
87
  return;
95
88
  }
@@ -97,20 +90,10 @@
97
90
  if (!drawFunc) {
98
91
  return;
99
92
  }
100
- drawFunc({
101
- context,
102
- particle,
103
- radius,
104
- opacity,
105
- delta,
106
- pixelRatio: container.retina.pixelRatio,
107
- fill: particle.shapeFill,
108
- stroke: strokeWidth > Constants_js_1.minStrokeWidth || !particle.shapeFill,
109
- transformData: { ...transformData },
110
- });
93
+ drawFunc(data);
111
94
  }
112
- function drawBeforeEffect(data) {
113
- const { container, context, particle, radius, opacity, strokeWidth, delta, transformData } = data;
95
+ function drawBeforeEffect(container, data) {
96
+ const { particle } = data;
114
97
  if (!particle.effect) {
115
98
  return;
116
99
  }
@@ -118,20 +101,10 @@
118
101
  if (!drawer?.drawBefore) {
119
102
  return;
120
103
  }
121
- drawer.drawBefore({
122
- context,
123
- particle,
124
- radius,
125
- opacity,
126
- delta,
127
- pixelRatio: container.retina.pixelRatio,
128
- fill: particle.shapeFill,
129
- stroke: strokeWidth > Constants_js_1.minStrokeWidth || !particle.shapeFill,
130
- transformData: { ...transformData },
131
- });
104
+ drawer.drawBefore(data);
132
105
  }
133
- function drawShape(data) {
134
- const { container, context, particle, radius, opacity, delta, strokeWidth, transformData } = data;
106
+ function drawShape(container, data) {
107
+ const { context, particle, stroke } = data;
135
108
  if (!particle.shape) {
136
109
  return;
137
110
  }
@@ -140,29 +113,19 @@
140
113
  return;
141
114
  }
142
115
  context.beginPath();
143
- drawer.draw({
144
- context,
145
- particle,
146
- radius,
147
- opacity,
148
- delta,
149
- pixelRatio: container.retina.pixelRatio,
150
- fill: particle.shapeFill,
151
- stroke: strokeWidth > Constants_js_1.minStrokeWidth || !particle.shapeFill,
152
- transformData: { ...transformData },
153
- });
116
+ drawer.draw(data);
154
117
  if (particle.shapeClose) {
155
118
  context.closePath();
156
119
  }
157
- if (strokeWidth > Constants_js_1.minStrokeWidth) {
120
+ if (stroke) {
158
121
  context.stroke();
159
122
  }
160
123
  if (particle.shapeFill) {
161
124
  context.fill();
162
125
  }
163
126
  }
164
- function drawShapeAfterDraw(data) {
165
- const { container, context, particle, radius, opacity, strokeWidth, delta, transformData } = data;
127
+ function drawShapeAfterDraw(container, data) {
128
+ const { particle } = data;
166
129
  if (!particle.shape) {
167
130
  return;
168
131
  }
@@ -170,20 +133,10 @@
170
133
  if (!drawer?.afterDraw) {
171
134
  return;
172
135
  }
173
- drawer.afterDraw({
174
- context,
175
- particle,
176
- radius,
177
- opacity,
178
- delta,
179
- pixelRatio: container.retina.pixelRatio,
180
- fill: particle.shapeFill,
181
- stroke: strokeWidth > Constants_js_1.minStrokeWidth || !particle.shapeFill,
182
- transformData: { ...transformData },
183
- });
136
+ drawer.afterDraw(data);
184
137
  }
185
- function drawShapeBeforeDraw(data) {
186
- const { container, context, particle, radius, opacity, strokeWidth, delta, transformData } = data;
138
+ function drawShapeBeforeDraw(container, data) {
139
+ const { particle } = data;
187
140
  if (!particle.shape) {
188
141
  return;
189
142
  }
@@ -191,17 +144,7 @@
191
144
  if (!drawer?.beforeDraw) {
192
145
  return;
193
146
  }
194
- drawer.beforeDraw({
195
- context,
196
- particle,
197
- radius,
198
- opacity,
199
- delta,
200
- pixelRatio: container.retina.pixelRatio,
201
- fill: particle.shapeFill,
202
- stroke: strokeWidth > Constants_js_1.minStrokeWidth || !particle.shapeFill,
203
- transformData: { ...transformData },
204
- });
147
+ drawer.beforeDraw(data);
205
148
  }
206
149
  function drawPlugin(context, plugin, delta) {
207
150
  if (!plugin.draw) {
@@ -33,6 +33,17 @@
33
33
  const TypeUtils_js_1 = require("./TypeUtils.js");
34
34
  const AnimationStatus_js_1 = require("../Enums/AnimationStatus.js");
35
35
  const Utils_js_1 = require("./Utils.js");
36
+ const styleCache = new Map(), maxCacheSize = 1000;
37
+ function getCachedStyle(key, generator) {
38
+ let cached = styleCache.get(key);
39
+ if (!cached) {
40
+ cached = generator();
41
+ if (styleCache.size < maxCacheSize) {
42
+ styleCache.set(key, cached);
43
+ }
44
+ }
45
+ return cached;
46
+ }
36
47
  function stringToRgba(engine, input) {
37
48
  if (!input) {
38
49
  return;
@@ -185,7 +196,8 @@
185
196
  };
186
197
  }
187
198
  function getStyleFromRgb(color, hdr, opacity) {
188
- return hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity);
199
+ const op = opacity ?? Constants_js_1.defaultOpacity, key = `rgb-${color.r.toString()}-${color.g.toString()}-${color.b.toString()}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
200
+ return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
189
201
  }
190
202
  function getHdrStyleFromRgb(color, opacity) {
191
203
  return `color(display-p3 ${(color.r / Constants_js_1.rgbMax).toString()} ${(color.g / Constants_js_1.rgbMax).toString()} ${(color.b / Constants_js_1.rgbMax).toString()} / ${(opacity ?? Constants_js_1.defaultOpacity).toString()})`;
@@ -194,7 +206,8 @@
194
206
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? Constants_js_1.defaultOpacity).toString()})`;
195
207
  }
196
208
  function getStyleFromHsl(color, hdr, opacity) {
197
- return hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity);
209
+ const op = opacity ?? Constants_js_1.defaultOpacity, key = `hsl-${color.h.toString()}-${color.s.toString()}-${color.l.toString()}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
210
+ return getCachedStyle(key, () => (hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity)));
198
211
  }
199
212
  function getHdrStyleFromHsl(color, opacity) {
200
213
  return getHdrStyleFromRgb(hslToRgb(color), opacity);
@@ -173,9 +173,10 @@
173
173
  return calcPositionOrRandomFromSize({ size: data.size, position });
174
174
  }
175
175
  function calcExactPositionOrRandomFromSize(data) {
176
+ const { position, size } = data;
176
177
  return {
177
- x: data.position?.x ?? getRandom() * data.size.width,
178
- y: data.position?.y ?? getRandom() * data.size.height,
178
+ x: position?.x ?? getRandom() * size.width,
179
+ y: position?.y ?? getRandom() * size.height,
179
180
  };
180
181
  }
181
182
  function calcExactPositionOrRandomFromSizeRanged(data) {
@@ -367,7 +367,7 @@
367
367
  const clonedStyle = safeDocument().createElement("div").style;
368
368
  for (const key in style) {
369
369
  const styleKey = style[key];
370
- if (!Object.prototype.hasOwnProperty.call(style, key) || (0, TypeUtils_js_1.isNull)(styleKey)) {
370
+ if (!Object.hasOwn(style, key) || (0, TypeUtils_js_1.isNull)(styleKey)) {
371
371
  continue;
372
372
  }
373
373
  const styleValue = style.getPropertyValue?.(styleKey);