custom-pixi-particles 4.31.0 → 4.33.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.
Files changed (55) hide show
  1. package/README.md +63 -2
  2. package/dist/index.d.ts +4 -1
  3. package/dist/index.js +32 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/behaviour/BehaviourNames.d.ts +1 -0
  6. package/dist/lib/behaviour/BehaviourNames.js +1 -0
  7. package/dist/lib/behaviour/BehaviourNames.js.map +1 -1
  8. package/dist/lib/behaviour/BehaviourRegistry.d.ts +44 -0
  9. package/dist/lib/behaviour/BehaviourRegistry.js +50 -0
  10. package/dist/lib/behaviour/BehaviourRegistry.js.map +1 -0
  11. package/dist/lib/behaviour/EmitterBehaviours.d.ts +10 -8
  12. package/dist/lib/behaviour/EmitterBehaviours.js +11 -9
  13. package/dist/lib/behaviour/EmitterBehaviours.js.map +1 -1
  14. package/dist/lib/behaviour/IBehaviour.d.ts +43 -0
  15. package/dist/lib/behaviour/IBehaviour.js +2 -0
  16. package/dist/lib/behaviour/IBehaviour.js.map +1 -0
  17. package/dist/lib/behaviour/PlaceholderBehaviour.d.ts +21 -0
  18. package/dist/lib/behaviour/PlaceholderBehaviour.js +36 -0
  19. package/dist/lib/behaviour/PlaceholderBehaviour.js.map +1 -0
  20. package/dist/lib/behaviour/SpawnBehaviour.d.ts +11 -3
  21. package/dist/lib/behaviour/SpawnBehaviour.js +89 -32
  22. package/dist/lib/behaviour/SpawnBehaviour.js.map +1 -1
  23. package/dist/lib/behaviour/TurbulenceBehaviour.js +1 -4
  24. package/dist/lib/behaviour/TurbulenceBehaviour.js.map +1 -1
  25. package/dist/lib/behaviour/Wireframe3DBehaviour.d.ts +140 -0
  26. package/dist/lib/behaviour/Wireframe3DBehaviour.js +572 -0
  27. package/dist/lib/behaviour/Wireframe3DBehaviour.js.map +1 -0
  28. package/dist/lib/behaviour/index.d.ts +4 -1
  29. package/dist/lib/behaviour/index.js +3 -1
  30. package/dist/lib/behaviour/index.js.map +1 -1
  31. package/dist/lib/effects/MeltEffect.d.ts +6 -0
  32. package/dist/lib/effects/MeltEffect.js +15 -2
  33. package/dist/lib/effects/MeltEffect.js.map +1 -1
  34. package/dist/lib/emission/AbstractEmission.d.ts +1 -1
  35. package/dist/lib/emission/AbstractEmission.js +1 -1
  36. package/dist/lib/emission/AbstractEmission.js.map +1 -1
  37. package/dist/lib/emission/RandomEmission.d.ts +1 -1
  38. package/dist/lib/emission/RandomEmission.js +2 -1
  39. package/dist/lib/emission/RandomEmission.js.map +1 -1
  40. package/dist/lib/emission/StandardEmission.d.ts +1 -1
  41. package/dist/lib/emission/StandardEmission.js +2 -1
  42. package/dist/lib/emission/StandardEmission.js.map +1 -1
  43. package/dist/lib/emission/UniformEmission.d.ts +5 -1
  44. package/dist/lib/emission/UniformEmission.js +8 -1
  45. package/dist/lib/emission/UniformEmission.js.map +1 -1
  46. package/dist/lib/parser/EmitterParser.d.ts +4 -2
  47. package/dist/lib/parser/EmitterParser.js +24 -6
  48. package/dist/lib/parser/EmitterParser.js.map +1 -1
  49. package/dist/lib/pixi/Renderer.d.ts +2 -0
  50. package/dist/lib/pixi/Renderer.js +14 -7
  51. package/dist/lib/pixi/Renderer.js.map +1 -1
  52. package/dist/lib/pixi/TestRenderer.d.ts +2 -1
  53. package/dist/lib/pixi/TestRenderer.js +26 -8
  54. package/dist/lib/pixi/TestRenderer.js.map +1 -1
  55. package/package.json +4 -1
package/README.md CHANGED
@@ -552,6 +552,60 @@ emitController: {
552
552
 
553
553
  Behaviours define how particles behave throughout their lifetime. Each behaviour has a `priority` (higher = processed first) and can be `enabled` or disabled.
554
554
 
555
+ #### Custom behaviours (IBehaviour)
556
+
557
+ You can add your own behaviours by implementing the **IBehaviour** interface (or extending the base **Behaviour** class) and registering them with **BehaviourRegistry**. Custom behaviours can then be used by name in your emitter config (e.g. from JSON or the editor).
558
+
559
+ ```javascript
560
+ import { Behaviour, BehaviourRegistry, customPixiParticles } from 'custom-pixi-particles'
561
+
562
+ // Extend Behaviour and implement required methods
563
+ class MyCustomBehaviour extends Behaviour {
564
+ enabled = true
565
+ priority = 0
566
+ getName() { return 'MyCustomBehaviour' }
567
+ getProps() { return { enabled: this.enabled, priority: this.priority, name: this.getName() } }
568
+ init(particle, model, turbulencePool) { /* ... */ }
569
+ apply(particle, deltaTime, model) { /* ... */ }
570
+ }
571
+
572
+ // Register so config can create it by name
573
+ BehaviourRegistry.register('MyCustomBehaviour', MyCustomBehaviour)
574
+
575
+ // Your emitter config can now include: { behaviours: [{ name: 'MyCustomBehaviour', ... }] }
576
+ ```
577
+
578
+ You can also add a custom behaviour instance at runtime: get the emitter from your renderer and call `emitter.behaviours.add(myCustomBehaviour)`.
579
+
580
+ ```javascript
581
+ // After creating the particle emitter
582
+ const particles = customPixiParticles.create({ textures, emitterConfig })
583
+ app.stage.addChild(particles)
584
+ particles.play()
585
+
586
+ // Add a custom behaviour at runtime
587
+ const myCustomBehaviour = new MyCustomBehaviour()
588
+ particles.emitter.behaviours.add(myCustomBehaviour)
589
+ // New and existing particles will use the new behaviour on the next update
590
+ ```
591
+
592
+ **Extending built-in behaviours:** All built-in behaviour classes are exported from the package so you can extend any of them: `SpawnBehaviour`, `LifeBehaviour`, `PositionBehaviour`, `ColorBehaviour`, `SizeBehaviour`, `AngularVelocityBehaviour`, `EmitDirectionBehaviour`, `RotationBehaviour`, `TurbulenceBehaviour`, `CollisionBehaviour`, `AttractionRepulsionBehaviour`, `NoiseBasedMotionBehaviour`, `ForceFieldsBehaviour`, `TimelineBehaviour`, `GroupingBehaviour`, `SoundReactiveBehaviour`, `LightEffectBehaviour`, `StretchBehaviour`, `TemperatureBehaviour`, `MoveToPointBehaviour`. Also exported: `Behaviour`, `BehaviourRegistry`, `EmitterBehaviours`, `BehaviourNames`.
593
+
594
+ **Replacing a built-in behaviour:** Register your class under the same name as a built-in (e.g. `SpawnBehaviour`) **before** creating the renderer or loading config. The registry is checked first, so your implementation is used instead. Use this for customizations like multiple trails on one shape, different trailing logic (e.g. CCV-style), or any variant of spawn/trail/position without changing the library.
595
+
596
+ ```javascript
597
+ import { BehaviourRegistry, SpawnBehaviour } from 'custom-pixi-particles'
598
+
599
+ class MySpawnBehaviour extends SpawnBehaviour {
600
+ getName() { return 'SpawnBehaviour' }
601
+ // Override init/apply, add multiple trails, custom trailing (e.g. CCV), etc.
602
+ }
603
+ BehaviourRegistry.register('SpawnBehaviour', MySpawnBehaviour)
604
+ // Then create renderer / load config that uses name: 'SpawnBehaviour'
605
+ ```
606
+
607
+ **Unregister:** `BehaviourRegistry.unregister('MyCustomBehaviour')` removes a registration. To restore a built-in after replacing it, unregister the custom name so the built-in is used again (built-ins are not in the registry by default).
608
+
555
609
  #### Life Behaviour
556
610
  Controls particle lifetime.
557
611
 
@@ -597,13 +651,20 @@ Defines where and how particles spawn. Supports multiple spawn types.
597
651
  // ... spawn type specific properties
598
652
  },
599
653
  ],
600
- trailingEnabled: false, // Enable trail effects
601
- spawnAlongTrail: false, // Spawn along entire trail
654
+ trailingEnabled: false, // Enable trail effects (path types only)
655
+ spawnAlongTrail: false, // true = uniform along trail; false = weighted toward leading edge
602
656
  trailSpeed: 1, // Trail animation speed
657
+ trailRepeat: true, // Loop the trail
658
+ trailStart: 0, // Start position on path (0–1)
659
+ trailRangeSegments: 20, // Sampling points along trail (higher = finer distribution)
660
+ trailRangeWeightFactor: 4, // Weight toward leading edge when spawnAlongTrail is false
661
+ trailRangeLength: 1, // Length of trail to spawn along (0–1); <1 avoids particles at path start
603
662
  name: 'SpawnBehaviour',
604
663
  }
605
664
  ```
606
665
 
666
+ **Trailing:** When `trailingEnabled` is true (path types like Frame, Ring, Bezier only), particles spawn along a moving “head” on the path. **Spawn Along Trail** on = even spread along the trail; off = more particles near the leading edge (**trailRangeWeightFactor**). **Trail Range Segments** sets how many sample points are used (higher = smoother). **Trail Range Length** (0–1) limits where particles appear: `1` = from path start to head; e.g. `0.2` = only the last 20% of the path, so the path start (e.g. top-left of a Frame) stays clear. **Trail Speed**, **Trail Repeat**, and **Trail Start** (0–1) control motion. When the path loops, the tail at the end stays visible until the head moves on.
667
+
607
668
  **Available Spawn Types:**
608
669
  - `Rectangle` - Uniform distribution in a rectangular area
609
670
  - `Ring` - Circular particle arrangement
package/dist/index.d.ts CHANGED
@@ -9,9 +9,12 @@ export type { IShatterEffectOptions, ShatterMode, IDissolveEffectOptions, Dissol
9
9
  * @param {ICustomPixiParticlesSettings} settings The settings for the renderer
10
10
  */
11
11
  declare const customPixiParticles: {
12
- create(settings: ICustomPixiParticlesSettings): Renderer;
12
+ create(settings: ICustomPixiParticlesSettings): any;
13
13
  };
14
14
  declare const _customPixiParticlesEditorOnly: {
15
15
  create(settings: ICustomPixiParticlesSettings): TestRenderer;
16
16
  };
17
+ export type { IBehaviour } from './lib/behaviour';
18
+ export { Behaviour, BehaviourRegistry, EmitterBehaviours, SpawnBehaviour, LifeBehaviour, PositionBehaviour, ColorBehaviour, SizeBehaviour, AngularVelocityBehaviour, EmitDirectionBehaviour, RotationBehaviour, TurbulenceBehaviour, CollisionBehaviour, AttractionRepulsionBehaviour, NoiseBasedMotionBehaviour, ForceFieldsBehaviour, TimelineBehaviour, GroupingBehaviour, SoundReactiveBehaviour, LightEffectBehaviour, StretchBehaviour, TemperatureBehaviour, MoveToPointBehaviour, Wireframe3DBehaviour, BehaviourNames, } from './lib/behaviour';
19
+ export { Application, Loader } from 'pixi.js';
17
20
  export { Renderer, customPixiParticles, _customPixiParticlesEditorOnly, ICustomPixiParticlesSettings, ShatterEffect, DissolveEffect, MagneticAssemblyEffect, GhostEffect, GlitchEffect, MeltEffect, };
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import Renderer from './lib/pixi/Renderer';
2
2
  import TestRenderer from './lib/pixi/TestRenderer';
3
3
  import { ShatterEffect, DissolveEffect, MagneticAssemblyEffect, GhostEffect, GlitchEffect, MeltEffect } from './lib/effects';
4
+ import { Container, Graphics } from 'pixi.js-legacy';
4
5
  /**
5
6
  * Constructs a renderer for custom pixi particles
6
7
  * @class Renderer
@@ -8,8 +9,10 @@ import { ShatterEffect, DissolveEffect, MagneticAssemblyEffect, GhostEffect, Gli
8
9
  */
9
10
  const customPixiParticles = {
10
11
  create(settings) {
12
+ var _a;
11
13
  const { textures, emitterConfig, animatedSpriteZeroPad = 2, animatedSpriteIndexToStart = 0, finishingTextures = [], vertices = true, position = true, rotation = true, uvs = true, tint = true, maxParticles = 10000, maxFPS = 60, minFPS = 30, tickerSpeed = 0.02, } = settings;
12
- return new Renderer({
14
+ const hasWireframe = (_a = emitterConfig === null || emitterConfig === void 0 ? void 0 : emitterConfig.behaviours) === null || _a === void 0 ? void 0 : _a.some((b) => b.name === 'Wireframe3DBehaviour');
15
+ const renderer = new Renderer({
13
16
  textures,
14
17
  animatedSpriteZeroPad,
15
18
  animatedSpriteIndexToStart,
@@ -25,6 +28,31 @@ const customPixiParticles = {
25
28
  minFPS,
26
29
  tickerSpeed,
27
30
  });
31
+ if (hasWireframe) {
32
+ const graphics = new Graphics();
33
+ const container = new Container();
34
+ container.addChild(graphics);
35
+ container.addChild(renderer);
36
+ renderer.wireframeGraphics = graphics;
37
+ Object.defineProperty(container, 'emitter', { get: () => renderer.emitter });
38
+ container.updateConfig = (c) => renderer.updateConfig(c);
39
+ container.updatePosition = (p) => renderer.updatePosition(p);
40
+ container.play = () => renderer.play();
41
+ container.stop = () => renderer.stop();
42
+ container.stopImmediately = () => renderer.stopImmediately();
43
+ container.pause = (p) => renderer.pause(p);
44
+ container.resume = () => renderer.resume();
45
+ container.start = () => renderer.start();
46
+ container.setTickerSpeed = (s) => renderer.setTickerSpeed(s);
47
+ container.updateTexture = () => renderer.updateTexture();
48
+ const origDestroy = container.destroy.bind(container);
49
+ container.destroy = () => {
50
+ renderer.destroy();
51
+ origDestroy();
52
+ };
53
+ return container;
54
+ }
55
+ return renderer;
28
56
  },
29
57
  };
30
58
  const _customPixiParticlesEditorOnly = {
@@ -42,5 +70,8 @@ const _customPixiParticlesEditorOnly = {
42
70
  });
43
71
  },
44
72
  };
73
+ export { Behaviour, BehaviourRegistry, EmitterBehaviours, SpawnBehaviour, LifeBehaviour, PositionBehaviour, ColorBehaviour, SizeBehaviour, AngularVelocityBehaviour, EmitDirectionBehaviour, RotationBehaviour, TurbulenceBehaviour, CollisionBehaviour, AttractionRepulsionBehaviour, NoiseBasedMotionBehaviour, ForceFieldsBehaviour, TimelineBehaviour, GroupingBehaviour, SoundReactiveBehaviour, LightEffectBehaviour, StretchBehaviour, TemperatureBehaviour, MoveToPointBehaviour, Wireframe3DBehaviour, BehaviourNames, } from './lib/behaviour';
74
+ // Re-export so demos can use one import (avoids loading Pixi twice)
75
+ export { Application, Loader } from 'pixi.js';
45
76
  export { Renderer, customPixiParticles, _customPixiParticlesEditorOnly, ShatterEffect, DissolveEffect, MagneticAssemblyEffect, GhostEffect, GlitchEffect, MeltEffect, };
46
77
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,qBAAqB,CAAA;AAE1C,OAAO,YAAY,MAAM,yBAAyB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,sBAAsB,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAI5H;;;;GAIG;AACH,MAAM,mBAAmB,GAAG;IAC1B,MAAM,CAAC,QAAsC;QAC3C,MAAM,EACJ,QAAQ,EACR,aAAa,EACb,qBAAqB,GAAG,CAAC,EACzB,0BAA0B,GAAG,CAAC,EAC9B,iBAAiB,GAAG,EAAE,EACtB,QAAQ,GAAG,IAAI,EACf,QAAQ,GAAG,IAAI,EACf,QAAQ,GAAG,IAAI,EACf,GAAG,GAAG,IAAI,EACV,IAAI,GAAG,IAAI,EACX,YAAY,GAAG,KAAK,EACpB,MAAM,GAAG,EAAE,EACX,MAAM,GAAG,EAAE,EACX,WAAW,GAAG,IAAI,GACnB,GAAG,QAAQ,CAAA;QACZ,OAAO,IAAI,QAAQ,CAAC;YAClB,QAAQ;YACR,qBAAqB;YACrB,0BAA0B;YAC1B,aAAa;YACb,iBAAiB;YACjB,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,GAAG;YACH,IAAI;YACJ,YAAY;YACZ,MAAM;YACN,MAAM;YACN,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AAED,MAAM,8BAA8B,GAAG;IACrC,MAAM,CAAC,QAAsC;QAC3C,MAAM,EACJ,QAAQ,EACR,aAAa,EACb,qBAAqB,GAAG,CAAC,EACzB,0BAA0B,GAAG,CAAC,EAC9B,iBAAiB,GAAG,EAAE,EACtB,MAAM,GAAG,EAAE,EACX,MAAM,GAAG,EAAE,EACX,WAAW,GAAG,IAAI,GACnB,GAAG,QAAQ,CAAA;QACZ,OAAO,IAAI,YAAY,CAAC;YACtB,QAAQ;YACR,qBAAqB;YACrB,0BAA0B;YAC1B,aAAa;YACb,iBAAiB;YACjB,MAAM;YACN,MAAM;YACN,WAAW;SACZ,CAAC,CAAA;IACJ,CAAC;CACF,CAAA;AAED,OAAO,EACL,QAAQ,EACR,mBAAmB,EACnB,8BAA8B,EAE9B,aAAa,EACb,cAAc,EACd,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,UAAU,GACX,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -19,5 +19,6 @@ declare const behaviourNames: {
19
19
  STRETCH_BEHAVIOUR: string;
20
20
  TEMPERATURE_BEHAVIOUR: string;
21
21
  MOVE_TO_POINT_BEHAVIOUR: string;
22
+ WIREFRAME_3D_BEHAVIOUR: string;
22
23
  };
23
24
  export default behaviourNames;
@@ -19,6 +19,7 @@ const behaviourNames = {
19
19
  STRETCH_BEHAVIOUR: 'StretchBehaviour',
20
20
  TEMPERATURE_BEHAVIOUR: 'TemperatureBehaviour',
21
21
  MOVE_TO_POINT_BEHAVIOUR: 'MoveToPointBehaviour',
22
+ WIREFRAME_3D_BEHAVIOUR: 'Wireframe3DBehaviour',
22
23
  };
23
24
  export default behaviourNames;
24
25
  //# sourceMappingURL=BehaviourNames.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BehaviourNames.js","sourceRoot":"","sources":["../../../src/lib/behaviour/BehaviourNames.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG;IACrB,iBAAiB,EAAE,0BAA0B;IAC7C,cAAc,EAAE,eAAe;IAC/B,eAAe,EAAE,gBAAgB;IACjC,kBAAkB,EAAE,mBAAmB;IACvC,cAAc,EAAE,eAAe;IAC/B,cAAc,EAAE,wBAAwB;IACxC,kBAAkB,EAAE,mBAAmB;IACvC,oBAAoB,EAAE,qBAAqB;IAC3C,mBAAmB,EAAE,oBAAoB;IACzC,8BAA8B,EAAE,8BAA8B;IAC9D,4BAA4B,EAAE,2BAA2B;IACzD,sBAAsB,EAAE,sBAAsB;IAC9C,eAAe,EAAE,gBAAgB;IACjC,kBAAkB,EAAE,mBAAmB;IACvC,kBAAkB,EAAE,mBAAmB;IACvC,wBAAwB,EAAE,wBAAwB;IAClD,sBAAsB,EAAE,sBAAsB;IAC9C,iBAAiB,EAAE,kBAAkB;IACrC,qBAAqB,EAAE,sBAAsB;IAC7C,uBAAuB,EAAE,sBAAsB;CAChD,CAAA;AAED,eAAe,cAAc,CAAA"}
1
+ {"version":3,"file":"BehaviourNames.js","sourceRoot":"","sources":["../../../src/lib/behaviour/BehaviourNames.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG;IACrB,iBAAiB,EAAE,0BAA0B;IAC7C,cAAc,EAAE,eAAe;IAC/B,eAAe,EAAE,gBAAgB;IACjC,kBAAkB,EAAE,mBAAmB;IACvC,cAAc,EAAE,eAAe;IAC/B,cAAc,EAAE,wBAAwB;IACxC,kBAAkB,EAAE,mBAAmB;IACvC,oBAAoB,EAAE,qBAAqB;IAC3C,mBAAmB,EAAE,oBAAoB;IACzC,8BAA8B,EAAE,8BAA8B;IAC9D,4BAA4B,EAAE,2BAA2B;IACzD,sBAAsB,EAAE,sBAAsB;IAC9C,eAAe,EAAE,gBAAgB;IACjC,kBAAkB,EAAE,mBAAmB;IACvC,kBAAkB,EAAE,mBAAmB;IACvC,wBAAwB,EAAE,wBAAwB;IAClD,sBAAsB,EAAE,sBAAsB;IAC9C,iBAAiB,EAAE,kBAAkB;IACrC,qBAAqB,EAAE,sBAAsB;IAC7C,uBAAuB,EAAE,sBAAsB;IAC/C,sBAAsB,EAAE,sBAAsB;CAC/C,CAAA;AAED,eAAe,cAAc,CAAA"}
@@ -0,0 +1,44 @@
1
+ import type { IBehaviour } from './IBehaviour';
2
+ type BehaviourConstructor = new () => IBehaviour;
3
+ /**
4
+ * Registry for custom behaviour classes. Register a class here so it can be
5
+ * created by name when loading emitter config (e.g. from JSON or the editor).
6
+ *
7
+ * @example
8
+ * import { Behaviour, BehaviourRegistry } from 'custom-pixi-particles'
9
+ *
10
+ * class MyCustomBehaviour extends Behaviour {
11
+ * enabled = true
12
+ * priority = 0
13
+ * getName() { return 'MyCustomBehaviour' }
14
+ * getProps() { return { enabled: this.enabled, priority: this.priority, name: this.getName() } }
15
+ * init(particle, model, turbulencePool) { ... }
16
+ * apply(particle, deltaTime, model) { ... }
17
+ * }
18
+ *
19
+ * BehaviourRegistry.register('MyCustomBehaviour', MyCustomBehaviour)
20
+ *
21
+ * // Now config can use: { behaviours: [{ name: 'MyCustomBehaviour', ... }] }
22
+ */
23
+ export declare const BehaviourRegistry: {
24
+ _behaviours: Map<string, BehaviourConstructor>;
25
+ /**
26
+ * Register a custom behaviour class by name. This name must match the string
27
+ * used in your emitter config (config.behaviours[].name).
28
+ */
29
+ register(name: string, BehaviourClass: BehaviourConstructor): void;
30
+ /**
31
+ * Unregister a custom behaviour by name.
32
+ */
33
+ unregister(name: string): boolean;
34
+ /**
35
+ * Get a registered behaviour constructor by name, or undefined if not registered.
36
+ * Used internally by EmitterParser when creating behaviours from config.
37
+ */
38
+ get(name: string): BehaviourConstructor | undefined;
39
+ /**
40
+ * Check if a name is registered (custom or built-in is not checked here).
41
+ */
42
+ has(name: string): boolean;
43
+ };
44
+ export {};
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Registry for custom behaviour classes. Register a class here so it can be
3
+ * created by name when loading emitter config (e.g. from JSON or the editor).
4
+ *
5
+ * @example
6
+ * import { Behaviour, BehaviourRegistry } from 'custom-pixi-particles'
7
+ *
8
+ * class MyCustomBehaviour extends Behaviour {
9
+ * enabled = true
10
+ * priority = 0
11
+ * getName() { return 'MyCustomBehaviour' }
12
+ * getProps() { return { enabled: this.enabled, priority: this.priority, name: this.getName() } }
13
+ * init(particle, model, turbulencePool) { ... }
14
+ * apply(particle, deltaTime, model) { ... }
15
+ * }
16
+ *
17
+ * BehaviourRegistry.register('MyCustomBehaviour', MyCustomBehaviour)
18
+ *
19
+ * // Now config can use: { behaviours: [{ name: 'MyCustomBehaviour', ... }] }
20
+ */
21
+ export const BehaviourRegistry = {
22
+ _behaviours: new Map(),
23
+ /**
24
+ * Register a custom behaviour class by name. This name must match the string
25
+ * used in your emitter config (config.behaviours[].name).
26
+ */
27
+ register(name, BehaviourClass) {
28
+ this._behaviours.set(name, BehaviourClass);
29
+ },
30
+ /**
31
+ * Unregister a custom behaviour by name.
32
+ */
33
+ unregister(name) {
34
+ return this._behaviours.delete(name);
35
+ },
36
+ /**
37
+ * Get a registered behaviour constructor by name, or undefined if not registered.
38
+ * Used internally by EmitterParser when creating behaviours from config.
39
+ */
40
+ get(name) {
41
+ return this._behaviours.get(name);
42
+ },
43
+ /**
44
+ * Check if a name is registered (custom or built-in is not checked here).
45
+ */
46
+ has(name) {
47
+ return this._behaviours.has(name);
48
+ },
49
+ };
50
+ //# sourceMappingURL=BehaviourRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BehaviourRegistry.js","sourceRoot":"","sources":["../../../src/lib/behaviour/BehaviourRegistry.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,WAAW,EAAE,IAAI,GAAG,EAAgC;IAEpD;;;OAGG;IACH,QAAQ,CAAC,IAAY,EAAE,cAAoC;QACzD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;IAC5C,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,IAAY;QACrB,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACtC,CAAC;IAED;;;OAGG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACnC,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACnC,CAAC;CACF,CAAA"}
@@ -1,29 +1,31 @@
1
+ import type { IBehaviour } from './IBehaviour';
1
2
  import Particle from '../Particle';
2
3
  import Model from '../Model';
3
4
  import TurbulencePool from '../util/turbulencePool';
4
5
  /**
5
- * EmitterBehaviours class manages the behaviour of particles
6
+ * EmitterBehaviours class manages the behaviour of particles.
7
+ * Accepts built-in behaviours and custom behaviours that implement IBehaviour.
6
8
  */
7
9
  export default class EmitterBehaviours {
8
- behaviours: any;
10
+ behaviours: IBehaviour[];
9
11
  /**
10
12
  * Gets all the enabled behaviours
11
13
  *
12
14
  * @return {any[]} The enabled behaviours
13
15
  */
14
- getAll: () => any;
16
+ getAll: () => IBehaviour[];
15
17
  /**
16
18
  * Clears all the stored behaviours
17
19
  */
18
20
  clear: () => void;
19
21
  /**
20
- * Adds a behaviour
22
+ * Adds a behaviour (built-in or custom implementing IBehaviour).
21
23
  *
22
- * @param {any} behaviour The behaviour to add
24
+ * @param {IBehaviour} behaviour The behaviour to add
23
25
  *
24
- * @return {any} The added behaviour
26
+ * @return {IBehaviour} The added behaviour
25
27
  */
26
- add: (behaviour: any) => any;
28
+ add: (behaviour: IBehaviour) => IBehaviour;
27
29
  /**
28
30
  * Checks if there are no behaviours stored
29
31
  *
@@ -37,7 +39,7 @@ export default class EmitterBehaviours {
37
39
  *
38
40
  * @return {any | null} The behaviour with the given name or null if not found
39
41
  */
40
- getByName: (name: string) => any;
42
+ getByName: (name: string) => IBehaviour | null;
41
43
  /**
42
44
  * Removes a behaviour by name
43
45
  *
@@ -1,7 +1,8 @@
1
1
  // src/lib/behaviour/EmitterBehaviours.ts
2
2
  // tslint:disable:prefer-for-of
3
3
  /**
4
- * EmitterBehaviours class manages the behaviour of particles
4
+ * EmitterBehaviours class manages the behaviour of particles.
5
+ * Accepts built-in behaviours and custom behaviours that implement IBehaviour.
5
6
  */
6
7
  export default class EmitterBehaviours {
7
8
  constructor() {
@@ -23,11 +24,11 @@ export default class EmitterBehaviours {
23
24
  this.behaviours = [];
24
25
  };
25
26
  /**
26
- * Adds a behaviour
27
+ * Adds a behaviour (built-in or custom implementing IBehaviour).
27
28
  *
28
- * @param {any} behaviour The behaviour to add
29
+ * @param {IBehaviour} behaviour The behaviour to add
29
30
  *
30
- * @return {any} The added behaviour
31
+ * @return {IBehaviour} The added behaviour
31
32
  */
32
33
  this.add = (behaviour) => {
33
34
  if (this.getByName(behaviour.getName()) !== null) {
@@ -108,8 +109,9 @@ export default class EmitterBehaviours {
108
109
  */
109
110
  this.update = (deltaTime) => {
110
111
  for (let i = 0; i < this.behaviours.length; ++i) {
111
- if (this.behaviours[i].update)
112
- this.behaviours[i].update(deltaTime);
112
+ const updateFn = this.behaviours[i].update;
113
+ if (updateFn)
114
+ updateFn(deltaTime);
113
115
  }
114
116
  };
115
117
  /**
@@ -119,9 +121,9 @@ export default class EmitterBehaviours {
119
121
  */
120
122
  this.onParticleRemoved = (particle) => {
121
123
  for (let i = 0; i < this.behaviours.length; ++i) {
122
- if (typeof this.behaviours[i].onParticleRemoved === 'function') {
123
- this.behaviours[i].onParticleRemoved(particle);
124
- }
124
+ const onRemoved = this.behaviours[i].onParticleRemoved;
125
+ if (onRemoved)
126
+ onRemoved(particle);
125
127
  }
126
128
  };
127
129
  }
@@ -1 +1 @@
1
- {"version":3,"file":"EmitterBehaviours.js","sourceRoot":"","sources":["../../../src/lib/behaviour/EmitterBehaviours.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EmitterBehaviours.js","sourceRoot":"","sources":["../../../src/lib/behaviour/EmitterBehaviours.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import type Particle from '../Particle';
2
+ import type Model from '../Model';
3
+ import type TurbulencePool from '../util/turbulencePool';
4
+ import type BehaviourParser from '../parser/BehaviourParser';
5
+ /**
6
+ * Interface that any behaviour must implement to work with the particle emitter.
7
+ * Use this for custom behaviours: implement IBehaviour (or extend Behaviour) and
8
+ * register your class with BehaviourRegistry so it can be used by name in config.
9
+ *
10
+ * @example
11
+ * // Custom behaviour implementing the interface
12
+ * class MyCustomBehaviour extends Behaviour {
13
+ * enabled = true
14
+ * priority = 0
15
+ * getName() { return 'MyCustomBehaviour' }
16
+ * getProps() { return { enabled: this.enabled, priority: this.priority, name: this.getName() } }
17
+ * init(particle, model, turbulencePool) { ... }
18
+ * apply(particle, deltaTime, model) { ... }
19
+ * }
20
+ * BehaviourRegistry.register('MyCustomBehaviour', MyCustomBehaviour)
21
+ */
22
+ export interface IBehaviour {
23
+ /** Whether this behaviour is active */
24
+ enabled: boolean;
25
+ /** Higher priority behaviours run first (default 0) */
26
+ priority: number;
27
+ /** Unique name used in config and registry (e.g. 'MyCustomBehaviour') */
28
+ getName(): string;
29
+ /** Parser for serializing/deserializing this behaviour (default: new BehaviourParser(this)) */
30
+ getParser(): BehaviourParser;
31
+ /** Plain object of configurable properties for save/load (must include enabled, priority, name) */
32
+ getProps(): Record<string, unknown>;
33
+ /** Called once per particle when it is created */
34
+ init(particle: Particle, model: Model, turbulencePool: TurbulencePool): void;
35
+ /** Called every frame per particle */
36
+ apply(particle: Particle, deltaTime: number, model: Model): void;
37
+ /** Optional: called once per frame (not per particle) */
38
+ update?(deltaTime: number): void;
39
+ /** Optional: called when a particle is removed */
40
+ onParticleRemoved?(particle: Particle): void;
41
+ /** Optional: draw wireframe/Graphics (e.g. Wireframe3DBehaviour) */
42
+ draw?(graphics: any, deltaTime: number): void;
43
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=IBehaviour.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IBehaviour.js","sourceRoot":"","sources":["../../../src/lib/behaviour/IBehaviour.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import type { IBehaviour } from './IBehaviour';
2
+ import type Particle from '../Particle';
3
+ import type Model from '../Model';
4
+ import type TurbulencePool from '../util/turbulencePool';
5
+ import BehaviourParser from '../parser/BehaviourParser';
6
+ /**
7
+ * Placeholder for unknown/custom behaviour names (e.g. when the editor loads
8
+ * a config that references a behaviour not registered in this context).
9
+ * No-ops in init/apply but preserves config for save/load.
10
+ */
11
+ export default class PlaceholderBehaviour implements IBehaviour {
12
+ enabled: boolean;
13
+ priority: number;
14
+ name: string;
15
+ constructor(name: string);
16
+ getName(): string;
17
+ getParser(): BehaviourParser;
18
+ getProps(): Record<string, unknown>;
19
+ init(_particle: Particle, _model: Model, _turbulencePool: TurbulencePool): void;
20
+ apply(_particle: Particle, _deltaTime: number, _model: Model): void;
21
+ }
@@ -0,0 +1,36 @@
1
+ import BehaviourParser from '../parser/BehaviourParser';
2
+ /**
3
+ * Placeholder for unknown/custom behaviour names (e.g. when the editor loads
4
+ * a config that references a behaviour not registered in this context).
5
+ * No-ops in init/apply but preserves config for save/load.
6
+ */
7
+ export default class PlaceholderBehaviour {
8
+ constructor(name) {
9
+ this.enabled = true;
10
+ this.priority = 0;
11
+ this.name = '';
12
+ this.name = name;
13
+ }
14
+ getName() {
15
+ return this.name;
16
+ }
17
+ getParser() {
18
+ return new BehaviourParser(this);
19
+ }
20
+ getProps() {
21
+ const props = {};
22
+ for (const key of Object.keys(this)) {
23
+ if (typeof this[key] !== 'function') {
24
+ props[key] = this[key];
25
+ }
26
+ }
27
+ return props;
28
+ }
29
+ init(_particle, _model, _turbulencePool) {
30
+ // no-op
31
+ }
32
+ apply(_particle, _deltaTime, _model) {
33
+ // no-op
34
+ }
35
+ }
36
+ //# sourceMappingURL=PlaceholderBehaviour.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PlaceholderBehaviour.js","sourceRoot":"","sources":["../../../src/lib/behaviour/PlaceholderBehaviour.ts"],"names":[],"mappings":"AAIA,OAAO,eAAe,MAAM,2BAA2B,CAAA;AAEvD;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;IAKvC,YAAY,IAAY;QAJxB,YAAO,GAAG,IAAI,CAAA;QACd,aAAQ,GAAG,CAAC,CAAA;QACZ,SAAI,GAAG,EAAE,CAAA;QAGP,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAA;IAClB,CAAC;IAED,SAAS;QACP,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;IAClC,CAAC;IAED,QAAQ;QACN,MAAM,KAAK,GAA4B,EAAE,CAAA;QACzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,IAAI,OAAQ,IAAY,CAAC,GAAG,CAAC,KAAK,UAAU,EAAE,CAAC;gBAC7C,KAAK,CAAC,GAAG,CAAC,GAAI,IAAY,CAAC,GAAG,CAAC,CAAA;YACjC,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,IAAI,CAAC,SAAmB,EAAE,MAAa,EAAE,eAA+B;QACtE,QAAQ;IACV,CAAC;IAED,KAAK,CAAC,SAAmB,EAAE,UAAkB,EAAE,MAAa;QAC1D,QAAQ;IACV,CAAC;CACF"}
@@ -12,7 +12,9 @@ export default class SpawnBehaviour extends Behaviour {
12
12
  trailStart: number;
13
13
  trailRangeSegments: number;
14
14
  trailRangeWeightFactor: number;
15
+ trailRangeLength: number;
15
16
  currentProgress: number;
17
+ trailJustWrapped: boolean;
16
18
  customPoints: any[];
17
19
  lastWordSettings: any;
18
20
  /**
@@ -21,12 +23,17 @@ export default class SpawnBehaviour extends Behaviour {
21
23
  */
22
24
  init: (particle: Particle) => void;
23
25
  apply: () => void;
26
+ /** Distance along path from progress p to head (end), going backward; path is 0..1 circular. */
27
+ private distanceFromHead;
24
28
  /**
25
- * Calculate trail positions along the range from trailStart to currentProgress.
29
+ * Calculate trail positions along the range. Uses trailRangeLength so only the "tail" is sampled.
30
+ * When the head wraps to the start of the path, we still spawn along the end of the previous loop
31
+ * so the tail at the frame end doesn't disappear.
26
32
  * @param {Object} point - The custom point configuration.
27
- * @returns {Point[]} List of positions along the trail.
33
+ * @param {boolean} uniformWeights - If true (spawnAlongTrail), equal probability.
34
+ * @returns {{ positions, probabilities }}
28
35
  */
29
- calculateTrailRangePositions: (point: any) => {
36
+ calculateTrailRangePositions: (point: any, uniformWeights?: boolean) => {
30
37
  positions: any[];
31
38
  probabilities: number[];
32
39
  };
@@ -85,6 +92,7 @@ export default class SpawnBehaviour extends Behaviour {
85
92
  trailStart: number;
86
93
  trailRangeSegments: number;
87
94
  trailRangeWeightFactor: number;
95
+ trailRangeLength: number;
88
96
  customPoints: any[];
89
97
  name: string;
90
98
  };