particle-network-bg 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -166,23 +166,56 @@ new ParticleNetwork(canvas, {
166
166
 
167
167
  ## Particle Types
168
168
 
169
- Use `particleTypes` to mix circle, asset, and liquid glass particles with full control:
169
+ Use `particleTypes` to mix circle, asset, and liquid glass particles with full control. Each entry can carry **per-type overrides** that shadow the global config:
170
170
 
171
171
  ```js
172
172
  new ParticleNetwork(canvas, {
173
+ particleCount: 100,
174
+ particleColor: "#000000",
175
+ particleOpacity: 1,
176
+ pulseEnabled: false,
173
177
  particleTypes: [
174
- { type: "circle", percentage: 50 },
175
- { type: "liquidGlass", percentage: 30 },
176
- { type: "asset", asset: "star", count: 20, liquidGlass: true },
178
+ // 50% circles override color and enable pulse just for these
179
+ { type: "circle", percentage: 50, color: "#ff6600", pulse: true, pulseSpeed: 0.03 },
180
+ // 30% liquid glass override glass config just for these
181
+ { type: "liquidGlass", percentage: 30, liquidGlass: { color: "#00ccff", opacity: 0.8 } },
182
+ // 20 asset particles with custom opacity
183
+ { type: "asset", asset: "star", count: 20, opacity: 0.7 },
177
184
  ],
178
185
  assets: { star: "https://..." },
179
- liquidGlass: { color: "#88ccff", blur: 12, contrast: 25, ... },
186
+ liquidGlass: { color: "#88ccff", blur: 12, contrast: 25 },
180
187
  });
181
188
  ```
182
189
 
183
- - **`circle`**: Normal circles
184
- - **`liquidGlass`**: Liquid glass blobs (merge when close)
185
- - **`asset`**: Icons/images; use `liquidGlass: true` to combine with glass
190
+ Per-type values are a **shallow override** on top of the root config. Omitted fields fall back to the global value, so existing usage without `particleTypes` stays unchanged.
191
+
192
+ ### Circle type overrides
193
+
194
+ | Field | Type | Description |
195
+ | ------------ | ------- | -------------------------------------------- |
196
+ | `color` | string | Particle color (hex). Overrides `particleColor` |
197
+ | `opacity` | number | Particle opacity (0–1). Overrides `particleOpacity` |
198
+ | `minRadius` | number | Min radius (px). Overrides root `minRadius` |
199
+ | `maxRadius` | number | Max radius (px). Overrides root `maxRadius` |
200
+ | `pulse` | boolean | Enable pulse. Overrides `pulseEnabled` |
201
+ | `pulseSpeed` | number | Pulse speed. Overrides root `pulseSpeed` |
202
+
203
+ ### Liquid glass type overrides
204
+
205
+ | Field | Type | Description |
206
+ | ------------ | ------------------------- | -------------------------------------------------------------- |
207
+ | `liquidGlass`| `Partial<LiquidGlassConfig>` | Shallow-merged over root `liquidGlass` (color, opacity, minRadius, etc.) |
208
+ | `pulse` | boolean | Enable pulse. Overrides `pulseEnabled` |
209
+ | `pulseSpeed` | number | Pulse speed. Overrides root `pulseSpeed` |
210
+
211
+ ### Asset type overrides
212
+
213
+ | Field | Type | Description |
214
+ | ------------ | ---------------------------------------- | ----------------------------------------------------------------- |
215
+ | `liquidGlass`| `boolean \| Partial<LiquidGlassConfig>` | `true` for glass rendering, or partial config for per-type glass |
216
+ | `opacity` | number | Particle opacity (0–1). Overrides `particleOpacity` |
217
+ | `pulse` | boolean | Enable pulse. Overrides `pulseEnabled` |
218
+ | `pulseSpeed` | number | Pulse speed. Overrides root `pulseSpeed` |
186
219
 
187
220
  ## Connection Rules
188
221
 
@@ -445,6 +478,9 @@ import type {
445
478
  LiquidGlassConfig,
446
479
  LiquidGlassHighlightPosition,
447
480
  ParticleTypeEntry,
481
+ CircleTypeEntry,
482
+ LiquidGlassTypeEntry,
483
+ AssetTypeEntry,
448
484
  ParticleAssetConfig,
449
485
  ChildParticleConfig,
450
486
  ChildParticlePosition,
@@ -432,6 +432,7 @@ var ParticleNetwork = class {
432
432
  this.particles.forEach((p) => {
433
433
  delete p.assetId;
434
434
  delete p.liquidGlass;
435
+ delete p.typeConfig;
435
436
  });
436
437
  if (particleTypes?.length) {
437
438
  const counts = [];
@@ -444,15 +445,16 @@ var ParticleNetwork = class {
444
445
  }
445
446
  if (count > 0) {
446
447
  if (pt.type === "circle") {
447
- counts.push({ liquidGlass: false, count });
448
+ counts.push({ entry: pt, liquidGlass: false, count });
448
449
  } else if (pt.type === "asset") {
449
450
  counts.push({
451
+ entry: pt,
450
452
  assetId: pt.asset,
451
- liquidGlass: pt.liquidGlass ?? false,
453
+ liquidGlass: !!pt.liquidGlass,
452
454
  count
453
455
  });
454
456
  } else {
455
- counts.push({ liquidGlass: true, count });
457
+ counts.push({ entry: pt, liquidGlass: true, count });
456
458
  }
457
459
  }
458
460
  }
@@ -463,9 +465,10 @@ var ParticleNetwork = class {
463
465
  [indices[i], indices[j]] = [indices[j], indices[i]];
464
466
  }
465
467
  let idx = 0;
466
- for (const { assetId, liquidGlass, count } of counts) {
468
+ for (const { entry, assetId, liquidGlass, count } of counts) {
467
469
  for (let c = 0; c < count && idx < indices.length; c++, idx++) {
468
470
  const p = this.particles[indices[idx]];
471
+ p.typeConfig = entry;
469
472
  if (assetId) p.assetId = assetId;
470
473
  p.liquidGlass = liquidGlass;
471
474
  if (liquidGlass) this.resizeAsLiquidGlass(p);
@@ -524,8 +527,10 @@ var ParticleNetwork = class {
524
527
  }
525
528
  resizeAsLiquidGlass(p) {
526
529
  const lg = this.getLiquidGlassConfig();
527
- const min = lg.minRadius ?? DEFAULT_LIQUID_GLASS.minRadius;
528
- const max = lg.maxRadius ?? DEFAULT_LIQUID_GLASS.maxRadius;
530
+ const tc = p.typeConfig;
531
+ const perTypeLg = tc && "liquidGlass" in tc && typeof tc.liquidGlass === "object" ? tc.liquidGlass : void 0;
532
+ const min = perTypeLg?.minRadius ?? lg.minRadius ?? DEFAULT_LIQUID_GLASS.minRadius;
533
+ const max = perTypeLg?.maxRadius ?? lg.maxRadius ?? DEFAULT_LIQUID_GLASS.maxRadius;
529
534
  p.radius = Math.random() * (max - min) + min;
530
535
  delete p.currentRadius;
531
536
  this.initBlob(p);
@@ -596,8 +601,11 @@ var ParticleNetwork = class {
596
601
  if (particle.isChild) {
597
602
  particle.currentRadius = particle.radius;
598
603
  } else {
599
- if (this.config.pulseEnabled) {
600
- this.pulseAngle += this.config.pulseSpeed;
604
+ const tc = particle.typeConfig;
605
+ const doPulse = tc?.pulse ?? this.config.pulseEnabled;
606
+ if (doPulse) {
607
+ const speed = tc?.pulseSpeed ?? this.config.pulseSpeed;
608
+ this.pulseAngle += speed;
601
609
  const pulseScale = Math.sin(this.pulseAngle) * 0.5 + 1;
602
610
  particle.currentRadius = particle.radius * pulseScale;
603
611
  } else {
@@ -798,7 +806,9 @@ var ParticleNetwork = class {
798
806
  blob.mouseStretchY *= 1 - smoothing;
799
807
  }
800
808
  draw3DFluidSphere(particle) {
801
- const lg = this.getLiquidGlassConfig();
809
+ const tc = particle.typeConfig;
810
+ const perTypeLg = tc && "liquidGlass" in tc && typeof tc.liquidGlass === "object" ? tc.liquidGlass : void 0;
811
+ const lg = perTypeLg ? { ...this.getLiquidGlassConfig(), ...perTypeLg } : this.getLiquidGlassConfig();
802
812
  const r = particle.currentRadius ?? particle.radius;
803
813
  if (r <= 0) return;
804
814
  if (!particle.blob) this.initBlob(particle);
@@ -883,7 +893,9 @@ var ParticleNetwork = class {
883
893
  this.draw3DFluidSphere(particle);
884
894
  return;
885
895
  }
886
- let opacity = this.config.particleOpacity;
896
+ const tc = particle.typeConfig;
897
+ const tcOpacity = tc && "opacity" in tc ? tc.opacity : void 0;
898
+ let opacity = tcOpacity ?? this.config.particleOpacity;
887
899
  if (this.config.depthEffectEnabled) {
888
900
  opacity *= 0.6 + 0.4 * particle.z;
889
901
  }
@@ -900,8 +912,9 @@ var ParticleNetwork = class {
900
912
  this.ctx.drawImage(img, x, y, size, size);
901
913
  }
902
914
  } else if (particle.isChild && particle.width != null && particle.height != null) {
915
+ const color = (tc && "color" in tc ? tc.color : void 0) ?? defaultColor;
903
916
  this.ctx.globalAlpha = opacity;
904
- this.ctx.fillStyle = defaultColor;
917
+ this.ctx.fillStyle = color;
905
918
  const w = particle.width;
906
919
  const h = particle.height;
907
920
  const br = particle.borderRadius ?? Math.min(w, h) / 2;
@@ -911,8 +924,9 @@ var ParticleNetwork = class {
911
924
  this.ctx.roundRect(x, y, w, h, br);
912
925
  this.ctx.fill();
913
926
  } else {
927
+ const color = (tc && "color" in tc ? tc.color : void 0) ?? defaultColor;
914
928
  this.ctx.globalAlpha = opacity;
915
- this.ctx.fillStyle = defaultColor;
929
+ this.ctx.fillStyle = color;
916
930
  this.ctx.beginPath();
917
931
  this.ctx.arc(particle.x, particle.y, r, 0, Math.PI * 2);
918
932
  this.ctx.fill();
package/dist/index.d.mts CHANGED
@@ -39,22 +39,37 @@ interface LiquidGlassConfig {
39
39
  /** Maximum radius (px) for liquid glass particles (overrides root maxRadius). */
40
40
  maxRadius?: number;
41
41
  }
42
- /** Particle type entry for mixing circle, asset, liquidGlass. */
43
- type ParticleTypeEntry = {
42
+ interface CircleTypeEntry {
44
43
  type: "circle";
44
+ percentage?: number;
45
45
  count?: number;
46
+ color?: string;
47
+ opacity?: number;
48
+ minRadius?: number;
49
+ maxRadius?: number;
50
+ pulse?: boolean;
51
+ pulseSpeed?: number;
52
+ }
53
+ interface LiquidGlassTypeEntry {
54
+ type: "liquidGlass";
46
55
  percentage?: number;
47
- } | {
56
+ count?: number;
57
+ liquidGlass?: Partial<LiquidGlassConfig>;
58
+ pulse?: boolean;
59
+ pulseSpeed?: number;
60
+ }
61
+ interface AssetTypeEntry {
48
62
  type: "asset";
49
63
  asset: string;
50
- count?: number;
51
64
  percentage?: number;
52
- liquidGlass?: boolean;
53
- } | {
54
- type: "liquidGlass";
55
65
  count?: number;
56
- percentage?: number;
57
- };
66
+ liquidGlass?: boolean | Partial<LiquidGlassConfig>;
67
+ opacity?: number;
68
+ pulse?: boolean;
69
+ pulseSpeed?: number;
70
+ }
71
+ /** Particle type entry for mixing circle, asset, liquidGlass with optional per-type overrides. */
72
+ type ParticleTypeEntry = CircleTypeEntry | LiquidGlassTypeEntry | AssetTypeEntry;
58
73
  /** Configuration for a child particle that holds a UI component. */
59
74
  interface ChildParticleConfig {
60
75
  /** Unique identifier linking this particle to a React/DOM child. */
@@ -191,6 +206,8 @@ interface Particle {
191
206
  borderRadius?: number;
192
207
  /** CSS overflow for the child content overlay. */
193
208
  overflow?: string;
209
+ /** Per-type config entry (shallow overrides root config). */
210
+ typeConfig?: ParticleTypeEntry;
194
211
  /** Smoothed x for overlay positioning. */
195
212
  smoothX?: number;
196
213
  /** Smoothed y for overlay positioning. */
@@ -276,4 +293,4 @@ declare class ParticleNetwork {
276
293
  reset(defaults: Partial<ParticleNetworkConfig>): void;
277
294
  }
278
295
 
279
- export { type ChildParticleConfig, type ChildParticlePosition, type ConnectionRules, type GradientType, type LiquidGlassConfig, type LiquidGlassHighlightPosition, type Particle, type ParticleAssetConfig, ParticleNetwork, type ParticleNetworkConfig, type ParticleTypeEntry };
296
+ export { type AssetTypeEntry, type ChildParticleConfig, type ChildParticlePosition, type CircleTypeEntry, type ConnectionRules, type GradientType, type LiquidGlassConfig, type LiquidGlassHighlightPosition, type LiquidGlassTypeEntry, type Particle, type ParticleAssetConfig, ParticleNetwork, type ParticleNetworkConfig, type ParticleTypeEntry };
package/dist/index.d.ts CHANGED
@@ -39,22 +39,37 @@ interface LiquidGlassConfig {
39
39
  /** Maximum radius (px) for liquid glass particles (overrides root maxRadius). */
40
40
  maxRadius?: number;
41
41
  }
42
- /** Particle type entry for mixing circle, asset, liquidGlass. */
43
- type ParticleTypeEntry = {
42
+ interface CircleTypeEntry {
44
43
  type: "circle";
44
+ percentage?: number;
45
45
  count?: number;
46
+ color?: string;
47
+ opacity?: number;
48
+ minRadius?: number;
49
+ maxRadius?: number;
50
+ pulse?: boolean;
51
+ pulseSpeed?: number;
52
+ }
53
+ interface LiquidGlassTypeEntry {
54
+ type: "liquidGlass";
46
55
  percentage?: number;
47
- } | {
56
+ count?: number;
57
+ liquidGlass?: Partial<LiquidGlassConfig>;
58
+ pulse?: boolean;
59
+ pulseSpeed?: number;
60
+ }
61
+ interface AssetTypeEntry {
48
62
  type: "asset";
49
63
  asset: string;
50
- count?: number;
51
64
  percentage?: number;
52
- liquidGlass?: boolean;
53
- } | {
54
- type: "liquidGlass";
55
65
  count?: number;
56
- percentage?: number;
57
- };
66
+ liquidGlass?: boolean | Partial<LiquidGlassConfig>;
67
+ opacity?: number;
68
+ pulse?: boolean;
69
+ pulseSpeed?: number;
70
+ }
71
+ /** Particle type entry for mixing circle, asset, liquidGlass with optional per-type overrides. */
72
+ type ParticleTypeEntry = CircleTypeEntry | LiquidGlassTypeEntry | AssetTypeEntry;
58
73
  /** Configuration for a child particle that holds a UI component. */
59
74
  interface ChildParticleConfig {
60
75
  /** Unique identifier linking this particle to a React/DOM child. */
@@ -191,6 +206,8 @@ interface Particle {
191
206
  borderRadius?: number;
192
207
  /** CSS overflow for the child content overlay. */
193
208
  overflow?: string;
209
+ /** Per-type config entry (shallow overrides root config). */
210
+ typeConfig?: ParticleTypeEntry;
194
211
  /** Smoothed x for overlay positioning. */
195
212
  smoothX?: number;
196
213
  /** Smoothed y for overlay positioning. */
@@ -276,4 +293,4 @@ declare class ParticleNetwork {
276
293
  reset(defaults: Partial<ParticleNetworkConfig>): void;
277
294
  }
278
295
 
279
- export { type ChildParticleConfig, type ChildParticlePosition, type ConnectionRules, type GradientType, type LiquidGlassConfig, type LiquidGlassHighlightPosition, type Particle, type ParticleAssetConfig, ParticleNetwork, type ParticleNetworkConfig, type ParticleTypeEntry };
296
+ export { type AssetTypeEntry, type ChildParticleConfig, type ChildParticlePosition, type CircleTypeEntry, type ConnectionRules, type GradientType, type LiquidGlassConfig, type LiquidGlassHighlightPosition, type LiquidGlassTypeEntry, type Particle, type ParticleAssetConfig, ParticleNetwork, type ParticleNetworkConfig, type ParticleTypeEntry };
package/dist/index.js CHANGED
@@ -456,6 +456,7 @@ var ParticleNetwork = class {
456
456
  this.particles.forEach((p) => {
457
457
  delete p.assetId;
458
458
  delete p.liquidGlass;
459
+ delete p.typeConfig;
459
460
  });
460
461
  if (particleTypes?.length) {
461
462
  const counts = [];
@@ -468,15 +469,16 @@ var ParticleNetwork = class {
468
469
  }
469
470
  if (count > 0) {
470
471
  if (pt.type === "circle") {
471
- counts.push({ liquidGlass: false, count });
472
+ counts.push({ entry: pt, liquidGlass: false, count });
472
473
  } else if (pt.type === "asset") {
473
474
  counts.push({
475
+ entry: pt,
474
476
  assetId: pt.asset,
475
- liquidGlass: pt.liquidGlass ?? false,
477
+ liquidGlass: !!pt.liquidGlass,
476
478
  count
477
479
  });
478
480
  } else {
479
- counts.push({ liquidGlass: true, count });
481
+ counts.push({ entry: pt, liquidGlass: true, count });
480
482
  }
481
483
  }
482
484
  }
@@ -487,9 +489,10 @@ var ParticleNetwork = class {
487
489
  [indices[i], indices[j]] = [indices[j], indices[i]];
488
490
  }
489
491
  let idx = 0;
490
- for (const { assetId, liquidGlass, count } of counts) {
492
+ for (const { entry, assetId, liquidGlass, count } of counts) {
491
493
  for (let c = 0; c < count && idx < indices.length; c++, idx++) {
492
494
  const p = this.particles[indices[idx]];
495
+ p.typeConfig = entry;
493
496
  if (assetId) p.assetId = assetId;
494
497
  p.liquidGlass = liquidGlass;
495
498
  if (liquidGlass) this.resizeAsLiquidGlass(p);
@@ -548,8 +551,10 @@ var ParticleNetwork = class {
548
551
  }
549
552
  resizeAsLiquidGlass(p) {
550
553
  const lg = this.getLiquidGlassConfig();
551
- const min = lg.minRadius ?? DEFAULT_LIQUID_GLASS.minRadius;
552
- const max = lg.maxRadius ?? DEFAULT_LIQUID_GLASS.maxRadius;
554
+ const tc = p.typeConfig;
555
+ const perTypeLg = tc && "liquidGlass" in tc && typeof tc.liquidGlass === "object" ? tc.liquidGlass : void 0;
556
+ const min = perTypeLg?.minRadius ?? lg.minRadius ?? DEFAULT_LIQUID_GLASS.minRadius;
557
+ const max = perTypeLg?.maxRadius ?? lg.maxRadius ?? DEFAULT_LIQUID_GLASS.maxRadius;
553
558
  p.radius = Math.random() * (max - min) + min;
554
559
  delete p.currentRadius;
555
560
  this.initBlob(p);
@@ -620,8 +625,11 @@ var ParticleNetwork = class {
620
625
  if (particle.isChild) {
621
626
  particle.currentRadius = particle.radius;
622
627
  } else {
623
- if (this.config.pulseEnabled) {
624
- this.pulseAngle += this.config.pulseSpeed;
628
+ const tc = particle.typeConfig;
629
+ const doPulse = tc?.pulse ?? this.config.pulseEnabled;
630
+ if (doPulse) {
631
+ const speed = tc?.pulseSpeed ?? this.config.pulseSpeed;
632
+ this.pulseAngle += speed;
625
633
  const pulseScale = Math.sin(this.pulseAngle) * 0.5 + 1;
626
634
  particle.currentRadius = particle.radius * pulseScale;
627
635
  } else {
@@ -822,7 +830,9 @@ var ParticleNetwork = class {
822
830
  blob.mouseStretchY *= 1 - smoothing;
823
831
  }
824
832
  draw3DFluidSphere(particle) {
825
- const lg = this.getLiquidGlassConfig();
833
+ const tc = particle.typeConfig;
834
+ const perTypeLg = tc && "liquidGlass" in tc && typeof tc.liquidGlass === "object" ? tc.liquidGlass : void 0;
835
+ const lg = perTypeLg ? { ...this.getLiquidGlassConfig(), ...perTypeLg } : this.getLiquidGlassConfig();
826
836
  const r = particle.currentRadius ?? particle.radius;
827
837
  if (r <= 0) return;
828
838
  if (!particle.blob) this.initBlob(particle);
@@ -907,7 +917,9 @@ var ParticleNetwork = class {
907
917
  this.draw3DFluidSphere(particle);
908
918
  return;
909
919
  }
910
- let opacity = this.config.particleOpacity;
920
+ const tc = particle.typeConfig;
921
+ const tcOpacity = tc && "opacity" in tc ? tc.opacity : void 0;
922
+ let opacity = tcOpacity ?? this.config.particleOpacity;
911
923
  if (this.config.depthEffectEnabled) {
912
924
  opacity *= 0.6 + 0.4 * particle.z;
913
925
  }
@@ -924,8 +936,9 @@ var ParticleNetwork = class {
924
936
  this.ctx.drawImage(img, x, y, size, size);
925
937
  }
926
938
  } else if (particle.isChild && particle.width != null && particle.height != null) {
939
+ const color = (tc && "color" in tc ? tc.color : void 0) ?? defaultColor;
927
940
  this.ctx.globalAlpha = opacity;
928
- this.ctx.fillStyle = defaultColor;
941
+ this.ctx.fillStyle = color;
929
942
  const w = particle.width;
930
943
  const h = particle.height;
931
944
  const br = particle.borderRadius ?? Math.min(w, h) / 2;
@@ -935,8 +948,9 @@ var ParticleNetwork = class {
935
948
  this.ctx.roundRect(x, y, w, h, br);
936
949
  this.ctx.fill();
937
950
  } else {
951
+ const color = (tc && "color" in tc ? tc.color : void 0) ?? defaultColor;
938
952
  this.ctx.globalAlpha = opacity;
939
- this.ctx.fillStyle = defaultColor;
953
+ this.ctx.fillStyle = color;
940
954
  this.ctx.beginPath();
941
955
  this.ctx.arc(particle.x, particle.y, r, 0, Math.PI * 2);
942
956
  this.ctx.fill();
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ParticleNetwork
3
- } from "./chunk-VMVSPMPB.mjs";
3
+ } from "./chunk-BMXQY2SK.mjs";
4
4
  export {
5
5
  ParticleNetwork
6
6
  };
package/dist/react.js CHANGED
@@ -463,6 +463,7 @@ var ParticleNetwork = class {
463
463
  this.particles.forEach((p) => {
464
464
  delete p.assetId;
465
465
  delete p.liquidGlass;
466
+ delete p.typeConfig;
466
467
  });
467
468
  if (particleTypes?.length) {
468
469
  const counts = [];
@@ -475,15 +476,16 @@ var ParticleNetwork = class {
475
476
  }
476
477
  if (count > 0) {
477
478
  if (pt.type === "circle") {
478
- counts.push({ liquidGlass: false, count });
479
+ counts.push({ entry: pt, liquidGlass: false, count });
479
480
  } else if (pt.type === "asset") {
480
481
  counts.push({
482
+ entry: pt,
481
483
  assetId: pt.asset,
482
- liquidGlass: pt.liquidGlass ?? false,
484
+ liquidGlass: !!pt.liquidGlass,
483
485
  count
484
486
  });
485
487
  } else {
486
- counts.push({ liquidGlass: true, count });
488
+ counts.push({ entry: pt, liquidGlass: true, count });
487
489
  }
488
490
  }
489
491
  }
@@ -494,9 +496,10 @@ var ParticleNetwork = class {
494
496
  [indices[i], indices[j]] = [indices[j], indices[i]];
495
497
  }
496
498
  let idx = 0;
497
- for (const { assetId, liquidGlass, count } of counts) {
499
+ for (const { entry, assetId, liquidGlass, count } of counts) {
498
500
  for (let c = 0; c < count && idx < indices.length; c++, idx++) {
499
501
  const p = this.particles[indices[idx]];
502
+ p.typeConfig = entry;
500
503
  if (assetId) p.assetId = assetId;
501
504
  p.liquidGlass = liquidGlass;
502
505
  if (liquidGlass) this.resizeAsLiquidGlass(p);
@@ -555,8 +558,10 @@ var ParticleNetwork = class {
555
558
  }
556
559
  resizeAsLiquidGlass(p) {
557
560
  const lg = this.getLiquidGlassConfig();
558
- const min = lg.minRadius ?? DEFAULT_LIQUID_GLASS.minRadius;
559
- const max = lg.maxRadius ?? DEFAULT_LIQUID_GLASS.maxRadius;
561
+ const tc = p.typeConfig;
562
+ const perTypeLg = tc && "liquidGlass" in tc && typeof tc.liquidGlass === "object" ? tc.liquidGlass : void 0;
563
+ const min = perTypeLg?.minRadius ?? lg.minRadius ?? DEFAULT_LIQUID_GLASS.minRadius;
564
+ const max = perTypeLg?.maxRadius ?? lg.maxRadius ?? DEFAULT_LIQUID_GLASS.maxRadius;
560
565
  p.radius = Math.random() * (max - min) + min;
561
566
  delete p.currentRadius;
562
567
  this.initBlob(p);
@@ -627,8 +632,11 @@ var ParticleNetwork = class {
627
632
  if (particle.isChild) {
628
633
  particle.currentRadius = particle.radius;
629
634
  } else {
630
- if (this.config.pulseEnabled) {
631
- this.pulseAngle += this.config.pulseSpeed;
635
+ const tc = particle.typeConfig;
636
+ const doPulse = tc?.pulse ?? this.config.pulseEnabled;
637
+ if (doPulse) {
638
+ const speed = tc?.pulseSpeed ?? this.config.pulseSpeed;
639
+ this.pulseAngle += speed;
632
640
  const pulseScale = Math.sin(this.pulseAngle) * 0.5 + 1;
633
641
  particle.currentRadius = particle.radius * pulseScale;
634
642
  } else {
@@ -829,7 +837,9 @@ var ParticleNetwork = class {
829
837
  blob.mouseStretchY *= 1 - smoothing;
830
838
  }
831
839
  draw3DFluidSphere(particle) {
832
- const lg = this.getLiquidGlassConfig();
840
+ const tc = particle.typeConfig;
841
+ const perTypeLg = tc && "liquidGlass" in tc && typeof tc.liquidGlass === "object" ? tc.liquidGlass : void 0;
842
+ const lg = perTypeLg ? { ...this.getLiquidGlassConfig(), ...perTypeLg } : this.getLiquidGlassConfig();
833
843
  const r = particle.currentRadius ?? particle.radius;
834
844
  if (r <= 0) return;
835
845
  if (!particle.blob) this.initBlob(particle);
@@ -914,7 +924,9 @@ var ParticleNetwork = class {
914
924
  this.draw3DFluidSphere(particle);
915
925
  return;
916
926
  }
917
- let opacity = this.config.particleOpacity;
927
+ const tc = particle.typeConfig;
928
+ const tcOpacity = tc && "opacity" in tc ? tc.opacity : void 0;
929
+ let opacity = tcOpacity ?? this.config.particleOpacity;
918
930
  if (this.config.depthEffectEnabled) {
919
931
  opacity *= 0.6 + 0.4 * particle.z;
920
932
  }
@@ -931,8 +943,9 @@ var ParticleNetwork = class {
931
943
  this.ctx.drawImage(img, x, y, size, size);
932
944
  }
933
945
  } else if (particle.isChild && particle.width != null && particle.height != null) {
946
+ const color = (tc && "color" in tc ? tc.color : void 0) ?? defaultColor;
934
947
  this.ctx.globalAlpha = opacity;
935
- this.ctx.fillStyle = defaultColor;
948
+ this.ctx.fillStyle = color;
936
949
  const w = particle.width;
937
950
  const h = particle.height;
938
951
  const br = particle.borderRadius ?? Math.min(w, h) / 2;
@@ -942,8 +955,9 @@ var ParticleNetwork = class {
942
955
  this.ctx.roundRect(x, y, w, h, br);
943
956
  this.ctx.fill();
944
957
  } else {
958
+ const color = (tc && "color" in tc ? tc.color : void 0) ?? defaultColor;
945
959
  this.ctx.globalAlpha = opacity;
946
- this.ctx.fillStyle = defaultColor;
960
+ this.ctx.fillStyle = color;
947
961
  this.ctx.beginPath();
948
962
  this.ctx.arc(particle.x, particle.y, r, 0, Math.PI * 2);
949
963
  this.ctx.fill();
package/dist/react.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ParticleNetwork
3
- } from "./chunk-VMVSPMPB.mjs";
3
+ } from "./chunk-BMXQY2SK.mjs";
4
4
 
5
5
  // src/react.tsx
6
6
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "particle-network-bg",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Interactive particle network animation for backgrounds",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",