pixi-particles-engine 0.1.9 → 0.1.10

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/dist/cjs/behaviours/rotation-curve-behaviour.d.ts +21 -0
  2. package/dist/cjs/behaviours/rotation-curve-behaviour.d.ts.map +1 -0
  3. package/dist/cjs/behaviours/rotation-curve-behaviour.js +26 -0
  4. package/dist/cjs/behaviours/rotation-curve-behaviour.js.map +1 -0
  5. package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts +12 -5
  6. package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts.map +1 -1
  7. package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.js +15 -5
  8. package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.js.map +1 -1
  9. package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts +15 -5
  10. package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts.map +1 -1
  11. package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js +36 -7
  12. package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js.map +1 -1
  13. package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.d.ts +41 -3
  14. package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.d.ts.map +1 -1
  15. package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.js +46 -5
  16. package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.js.map +1 -1
  17. package/dist/cjs/index.d.ts +1 -0
  18. package/dist/cjs/index.d.ts.map +1 -1
  19. package/dist/cjs/index.js +1 -0
  20. package/dist/cjs/index.js.map +1 -1
  21. package/dist/cjs/px-particle.d.ts +7 -2
  22. package/dist/cjs/px-particle.d.ts.map +1 -1
  23. package/dist/cjs/px-particle.js +17 -4
  24. package/dist/cjs/px-particle.js.map +1 -1
  25. package/dist/esm/behaviours/rotation-curve-behaviour.d.ts +21 -0
  26. package/dist/esm/behaviours/rotation-curve-behaviour.d.ts.map +1 -0
  27. package/dist/esm/behaviours/rotation-curve-behaviour.js +22 -0
  28. package/dist/esm/behaviours/rotation-curve-behaviour.js.map +1 -0
  29. package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts +12 -5
  30. package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts.map +1 -1
  31. package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.js +15 -5
  32. package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.js.map +1 -1
  33. package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts +15 -5
  34. package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts.map +1 -1
  35. package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js +36 -7
  36. package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js.map +1 -1
  37. package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.d.ts +41 -3
  38. package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.d.ts.map +1 -1
  39. package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.js +46 -5
  40. package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.js.map +1 -1
  41. package/dist/esm/index.d.ts +1 -0
  42. package/dist/esm/index.d.ts.map +1 -1
  43. package/dist/esm/index.js +1 -0
  44. package/dist/esm/index.js.map +1 -1
  45. package/dist/esm/px-particle.d.ts +7 -2
  46. package/dist/esm/px-particle.d.ts.map +1 -1
  47. package/dist/esm/px-particle.js +17 -4
  48. package/dist/esm/px-particle.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/behaviours/rotation-curve-behaviour.ts +32 -0
  51. package/src/behaviours/spawn-behaviours/circle-spawn-behaviour.ts +18 -5
  52. package/src/behaviours/spawn-behaviours/rectangle-spawn-behaviour.ts +41 -8
  53. package/src/behaviours/static-behaviours/static-rotation-behaviour.ts +77 -6
  54. package/src/index.ts +1 -0
  55. package/src/px-particle.ts +21 -4
@@ -1 +1 @@
1
- {"version":3,"file":"circle-spawn-behaviour.js","sourceRoot":"","sources":["../../../../src/behaviours/spawn-behaviours/circle-spawn-behaviour.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,OAAO,oBAAoB;IAG7B,YAA6B,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QAF3B,aAAQ,GAAG,CAAC,GAAG,CAAC;IAEc,CAAC;IAExC,OAAO,CAAC,CAAa;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QAE1C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAEjD,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;CACJ"}
1
+ {"version":3,"file":"circle-spawn-behaviour.js","sourceRoot":"","sources":["../../../../src/behaviours/spawn-behaviours/circle-spawn-behaviour.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,oBAAoB;IAG7B,YACW,MAAc,EACd,cAAsB,CAAC;QADvB,WAAM,GAAN,MAAM,CAAQ;QACd,gBAAW,GAAX,WAAW,CAAY;QAJlB,aAAQ,GAAG,CAAC,GAAG,CAAC;IAK7B,CAAC;IAEG,OAAO,CAAC,CAAa;QACxB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QAE1C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QAEpD,wCAAwC;QACxC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC;QAEnE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;CACJ"}
@@ -1,13 +1,23 @@
1
1
  import { PxParticle } from "../../px-particle";
2
2
  import { Behaviour } from "../../behaviour";
3
3
  /**
4
- * Spawns particles uniformly inside a rectangle centered at (0, 0).
5
- * */
4
+ * Spawns particles inside a rectangular border/ring centered at (0, 0).
5
+ *
6
+ * Outer size:
7
+ * width x height
8
+ *
9
+ * Inner empty area:
10
+ * innerWidth x innerHeight
11
+ *
12
+ * Particles spawn only in the area between the outer and inner rectangles.
13
+ */
6
14
  export declare class RectangleSpawnBehaviour implements Behaviour {
7
- private readonly width;
8
- private readonly height;
15
+ width: number;
16
+ height: number;
17
+ innerWidth: number;
18
+ innerHeight: number;
9
19
  readonly priority = -100;
10
- constructor(width: number, height: number);
20
+ constructor(width: number, height: number, innerWidth?: number, innerHeight?: number);
11
21
  onSpawn(p: PxParticle): void;
12
22
  /** Inclusive-exclusive uniform random. */
13
23
  private rand;
@@ -1 +1 @@
1
- {"version":3,"file":"rectangle-spawn-behaviour.d.ts","sourceRoot":"","sources":["../../../../src/behaviours/spawn-behaviours/rectangle-spawn-behaviour.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;KAEK;AACL,qBAAa,uBAAwB,YAAW,SAAS;IAIjD,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJ3B,SAAgB,QAAQ,QAAQ;gBAGX,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;IAG5B,OAAO,CAAC,CAAC,EAAE,UAAU;IAQ5B,0CAA0C;IAC1C,OAAO,CAAC,IAAI;CAGf"}
1
+ {"version":3,"file":"rectangle-spawn-behaviour.d.ts","sourceRoot":"","sources":["../../../../src/behaviours/spawn-behaviours/rectangle-spawn-behaviour.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,YAAW,SAAS;IAI1C,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,MAAM;IAGd,UAAU,EAAE,MAAM;IAClB,WAAW,EAAE,MAAM;IAR9B,SAAgB,QAAQ,QAAQ;gBAGrB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAGd,UAAU,GAAE,MAAU,EACtB,WAAW,GAAE,MAAU;IAG3B,OAAO,CAAC,CAAC,EAAE,UAAU;IA6B5B,0CAA0C;IAC1C,OAAO,CAAC,IAAI;CAGf"}
@@ -1,17 +1,46 @@
1
1
  /**
2
- * Spawns particles uniformly inside a rectangle centered at (0, 0).
3
- * */
2
+ * Spawns particles inside a rectangular border/ring centered at (0, 0).
3
+ *
4
+ * Outer size:
5
+ * width x height
6
+ *
7
+ * Inner empty area:
8
+ * innerWidth x innerHeight
9
+ *
10
+ * Particles spawn only in the area between the outer and inner rectangles.
11
+ */
4
12
  export class RectangleSpawnBehaviour {
5
- constructor(width, height) {
13
+ constructor(width, height,
14
+ // Optional inner empty rectangle
15
+ innerWidth = 0, innerHeight = 0) {
6
16
  this.width = width;
7
17
  this.height = height;
18
+ this.innerWidth = innerWidth;
19
+ this.innerHeight = innerHeight;
8
20
  this.priority = -100;
9
21
  }
10
22
  onSpawn(p) {
11
- const hw = this.width * 0.5;
12
- const hh = this.height * 0.5;
13
- p.x = this.rand(-hw, hw);
14
- p.y = this.rand(-hh, hh);
23
+ const outerHW = this.width * 0.5;
24
+ const outerHH = this.height * 0.5;
25
+ const innerHW = this.innerWidth * 0.5;
26
+ const innerHH = this.innerHeight * 0.5;
27
+ // No inner hole -> normal rectangle spawn
28
+ if (this.innerWidth <= 0 || this.innerHeight <= 0) {
29
+ p.x = this.rand(-outerHW, outerHW);
30
+ p.y = this.rand(-outerHH, outerHH);
31
+ return;
32
+ }
33
+ // Pick a random point until it lands outside the inner rectangle
34
+ while (true) {
35
+ const x = this.rand(-outerHW, outerHW);
36
+ const y = this.rand(-outerHH, outerHH);
37
+ const insideInner = x > -innerHW && x < innerHW && y > -innerHH && y < innerHH;
38
+ if (!insideInner) {
39
+ p.x = x;
40
+ p.y = y;
41
+ return;
42
+ }
43
+ }
15
44
  }
16
45
  /** Inclusive-exclusive uniform random. */
17
46
  rand(min, max) {
@@ -1 +1 @@
1
- {"version":3,"file":"rectangle-spawn-behaviour.js","sourceRoot":"","sources":["../../../../src/behaviours/spawn-behaviours/rectangle-spawn-behaviour.ts"],"names":[],"mappings":"AAGA;;KAEK;AACL,MAAM,OAAO,uBAAuB;IAGhC,YACqB,KAAa,EACb,MAAc;QADd,UAAK,GAAL,KAAK,CAAQ;QACb,WAAM,GAAN,MAAM,CAAQ;QAJnB,aAAQ,GAAG,CAAC,GAAG,CAAC;IAK7B,CAAC;IAEG,OAAO,CAAC,CAAa;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;QAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAE7B,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,0CAA0C;IAClC,IAAI,CAAC,GAAW,EAAE,GAAW;QACjC,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IAC7C,CAAC;CACJ"}
1
+ {"version":3,"file":"rectangle-spawn-behaviour.js","sourceRoot":"","sources":["../../../../src/behaviours/spawn-behaviours/rectangle-spawn-behaviour.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AACH,MAAM,OAAO,uBAAuB;IAGhC,YACW,KAAa,EACb,MAAc;IAErB,iCAAiC;IAC1B,aAAqB,CAAC,EACtB,cAAsB,CAAC;QALvB,UAAK,GAAL,KAAK,CAAQ;QACb,WAAM,GAAN,MAAM,CAAQ;QAGd,eAAU,GAAV,UAAU,CAAY;QACtB,gBAAW,GAAX,WAAW,CAAY;QARlB,aAAQ,GAAG,CAAC,GAAG,CAAC;IAS7B,CAAC;IAEG,OAAO,CAAC,CAAa;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC;QAElC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;QAEvC,0CAA0C;QAC1C,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC;YAChD,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACnC,OAAO;QACX,CAAC;QAED,iEAAiE;QACjE,OAAO,IAAI,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAEvC,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,GAAG,OAAO,CAAC;YAE/E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACR,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACR,OAAO;YACX,CAAC;QACL,CAAC;IACL,CAAC;IAED,0CAA0C;IAClC,IAAI,CAAC,GAAW,EAAE,GAAW;QACjC,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IAC7C,CAAC;CACJ"}
@@ -4,13 +4,38 @@ import { PxParticle } from "../../px-particle";
4
4
  * Sets a particle's angular velocity at spawn time.
5
5
  *
6
6
  * Does NOT modify rotation per frame directly.
7
- * Instead, it initializes `angleV`, which the emitter integrates each tick.
7
+ * Instead, it initializes `angleVBase`, which the emitter integrates each tick.
8
8
  *
9
+ * Supports:
10
+ *
11
+ * - Fixed value:
12
+ * 2
13
+ *
14
+ * - Random range:
15
+ * { min: -3, max: 3 }
16
+ *
17
+ * - Random range with minimum absolute magnitude:
18
+ * { min: -3, max: 3, minAbs: 2 }
19
+ *
20
+ * Result:
21
+ * [-3 .. -2] U [2 .. 3]
9
22
  */
10
23
  export declare class StaticRotationBehaviour implements Behaviour {
11
24
  speed: number | {
12
25
  min: number;
13
26
  max: number;
27
+ /**
28
+ * Optional minimum absolute value.
29
+ *
30
+ * Example:
31
+ * min=-3
32
+ * max=3
33
+ * minAbs=2
34
+ *
35
+ * Produces:
36
+ * [-3..-2] U [2..3]
37
+ */
38
+ minAbs?: number;
14
39
  };
15
40
  readonly priority = -60;
16
41
  readonly requires: {
@@ -18,13 +43,26 @@ export declare class StaticRotationBehaviour implements Behaviour {
18
43
  };
19
44
  /**
20
45
  * @param speed
21
- * - number → fixed angular velocity (radians/sec)
22
- * - {min,max} → randomized angular velocity per particle
46
+ * - number → fixed angular velocity
47
+ * - object → randomized angular velocity
23
48
  */
24
49
  constructor(speed: number | {
25
50
  min: number;
26
51
  max: number;
52
+ /**
53
+ * Optional minimum absolute value.
54
+ *
55
+ * Example:
56
+ * min=-3
57
+ * max=3
58
+ * minAbs=2
59
+ *
60
+ * Produces:
61
+ * [-3..-2] U [2..3]
62
+ */
63
+ minAbs?: number;
27
64
  });
28
65
  onSpawn(p: PxParticle): void;
66
+ private randomRange;
29
67
  }
30
68
  //# sourceMappingURL=static-rotation-behaviour.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"static-rotation-behaviour.d.ts","sourceRoot":"","sources":["../../../../src/behaviours/static-behaviours/static-rotation-behaviour.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;;GAMG;AACH,qBAAa,uBAAwB,YAAW,SAAS;IAUlC,KAAK,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAT/D,SAAgB,QAAQ,OAAO;IAE/B,SAAgB,QAAQ;;MAAsB;IAE9C;;;;OAIG;gBACgB,KAAK,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE;IAExD,OAAO,CAAC,CAAC,EAAE,UAAU;CAK/B"}
1
+ {"version":3,"file":"static-rotation-behaviour.d.ts","sourceRoot":"","sources":["../../../../src/behaviours/static-behaviours/static-rotation-behaviour.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,uBAAwB,YAAW,SAAS;IAW1C,KAAK,EACN,MAAM,GACN;QACI,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QAEZ;;;;;;;;;;WAUG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB;IA5BX,SAAgB,QAAQ,OAAO;IAE/B,SAAgB,QAAQ;;MAAsB;IAE9C;;;;OAIG;gBAEQ,KAAK,EACN,MAAM,GACN;QACI,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QAEZ;;;;;;;;;;WAUG;QACH,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB;IAGJ,OAAO,CAAC,CAAC,EAAE,UAAU;IAM5B,OAAO,CAAC,WAAW;CAqCtB"}
@@ -2,14 +2,27 @@
2
2
  * Sets a particle's angular velocity at spawn time.
3
3
  *
4
4
  * Does NOT modify rotation per frame directly.
5
- * Instead, it initializes `angleV`, which the emitter integrates each tick.
5
+ * Instead, it initializes `angleVBase`, which the emitter integrates each tick.
6
6
  *
7
+ * Supports:
8
+ *
9
+ * - Fixed value:
10
+ * 2
11
+ *
12
+ * - Random range:
13
+ * { min: -3, max: 3 }
14
+ *
15
+ * - Random range with minimum absolute magnitude:
16
+ * { min: -3, max: 3, minAbs: 2 }
17
+ *
18
+ * Result:
19
+ * [-3 .. -2] U [2 .. 3]
7
20
  */
8
21
  export class StaticRotationBehaviour {
9
22
  /**
10
23
  * @param speed
11
- * - number → fixed angular velocity (radians/sec)
12
- * - {min,max} → randomized angular velocity per particle
24
+ * - number → fixed angular velocity
25
+ * - object → randomized angular velocity
13
26
  */
14
27
  constructor(speed) {
15
28
  this.speed = speed;
@@ -17,8 +30,36 @@ export class StaticRotationBehaviour {
17
30
  this.requires = { rotation: true };
18
31
  }
19
32
  onSpawn(p) {
20
- const s = typeof this.speed === "number" ? this.speed : this.speed.min + Math.random() * (this.speed.max - this.speed.min);
21
- p.angleV = s;
33
+ const s = typeof this.speed === "number" ? this.speed : this.randomRange(this.speed.min, this.speed.max, this.speed.minAbs);
34
+ p.angleVBase = s;
35
+ }
36
+ randomRange(min, max, minAbs) {
37
+ // Normal range
38
+ if (minAbs == null || minAbs <= 0) {
39
+ return min + Math.random() * (max - min);
40
+ }
41
+ // If the excluded center does not intersect range,
42
+ // fallback to normal random
43
+ if (min >= minAbs || max <= -minAbs) {
44
+ return min + Math.random() * (max - min);
45
+ }
46
+ const leftMin = min;
47
+ const leftMax = Math.min(-minAbs, max);
48
+ const rightMin = Math.max(minAbs, min);
49
+ const rightMax = max;
50
+ const leftSize = Math.max(0, leftMax - leftMin);
51
+ const rightSize = Math.max(0, rightMax - rightMin);
52
+ const total = leftSize + rightSize;
53
+ if (total <= 0) {
54
+ return 0;
55
+ }
56
+ const pick = Math.random() * total;
57
+ // Left segment
58
+ if (pick < leftSize) {
59
+ return leftMin + Math.random() * leftSize;
60
+ }
61
+ // Right segment
62
+ return rightMin + Math.random() * rightSize;
22
63
  }
23
64
  }
24
65
  //# sourceMappingURL=static-rotation-behaviour.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"static-rotation-behaviour.js","sourceRoot":"","sources":["../../../../src/behaviours/static-behaviours/static-rotation-behaviour.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,OAAO,uBAAuB;IAKhC;;;;OAIG;IACH,YAAmB,KAA4C;QAA5C,UAAK,GAAL,KAAK,CAAuC;QAT/C,aAAQ,GAAG,CAAC,EAAE,CAAC;QAEf,aAAQ,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAOoB,CAAC;IAE5D,OAAO,CAAC,CAAa;QACxB,MAAM,CAAC,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE3H,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACjB,CAAC;CACJ"}
1
+ {"version":3,"file":"static-rotation-behaviour.js","sourceRoot":"","sources":["../../../../src/behaviours/static-behaviours/static-rotation-behaviour.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,uBAAuB;IAKhC;;;;OAIG;IACH,YACW,KAkBA;QAlBA,UAAK,GAAL,KAAK,CAkBL;QA5BK,aAAQ,GAAG,CAAC,EAAE,CAAC;QAEf,aAAQ,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IA2B3C,CAAC;IAEG,OAAO,CAAC,CAAa;QACxB,MAAM,CAAC,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAE5H,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;IACrB,CAAC;IAEO,WAAW,CAAC,GAAW,EAAE,GAAW,EAAE,MAAe;QACzD,eAAe;QACf,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;QAC7C,CAAC;QAED,mDAAmD;QACnD,4BAA4B;QAC5B,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC;QACpB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,GAAG,CAAC;QAErB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC;QAChD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;QAEnD,MAAM,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QAEnC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACb,OAAO,CAAC,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC;QAEnC,eAAe;QACf,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;YAClB,OAAO,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC;QAC9C,CAAC;QAED,gBAAgB;QAChB,OAAO,QAAQ,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC;IAChD,CAAC;CACJ"}
@@ -13,6 +13,7 @@ export * from "./behaviours/spawn-behaviours/circle-spawn-behaviour";
13
13
  export * from "./behaviours/spawn-behaviours/rectangle-spawn-behaviour";
14
14
  export * from "./behaviours/static-behaviours/static-rotation-behaviour";
15
15
  export * from "./behaviours/static-behaviours/static-scale-behaviour";
16
+ export * from "./behaviours/rotation-curve-behaviour";
16
17
  export * from "./texture-providers/animated-texture-provider";
17
18
  export * from "./texture-providers/single-texture-provider";
18
19
  export * from "./texture-providers/weighted-texture-provider";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2DAA2D,CAAC;AAC1E,cAAc,yDAAyD,CAAC;AACxE,cAAc,sDAAsD,CAAC;AACrE,cAAc,yDAAyD,CAAC;AACxE,cAAc,0DAA0D,CAAC;AACzE,cAAc,uDAAuD,CAAC;AACtE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2DAA2D,CAAC;AAC1E,cAAc,yDAAyD,CAAC;AACxE,cAAc,sDAAsD,CAAC;AACrE,cAAc,yDAAyD,CAAC;AACxE,cAAc,0DAA0D,CAAC;AACzE,cAAc,uDAAuD,CAAC;AACtE,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC"}
package/dist/esm/index.js CHANGED
@@ -13,6 +13,7 @@ export * from "./behaviours/spawn-behaviours/circle-spawn-behaviour.js";
13
13
  export * from "./behaviours/spawn-behaviours/rectangle-spawn-behaviour.js";
14
14
  export * from "./behaviours/static-behaviours/static-rotation-behaviour.js";
15
15
  export * from "./behaviours/static-behaviours/static-scale-behaviour.js";
16
+ export * from "./behaviours/rotation-curve-behaviour.js";
16
17
  export * from "./texture-providers/animated-texture-provider.js";
17
18
  export * from "./texture-providers/single-texture-provider.js";
18
19
  export * from "./texture-providers/weighted-texture-provider.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2DAA2D,CAAC;AAC1E,cAAc,yDAAyD,CAAC;AACxE,cAAc,sDAAsD,CAAC;AACrE,cAAc,yDAAyD,CAAC;AACxE,cAAc,0DAA0D,CAAC;AACzE,cAAc,uDAAuD,CAAC;AACtE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2DAA2D,CAAC;AAC1E,cAAc,yDAAyD,CAAC;AACxE,cAAc,sDAAsD,CAAC;AACrE,cAAc,yDAAyD,CAAC;AACxE,cAAc,0DAA0D,CAAC;AACzE,cAAc,uDAAuD,CAAC;AACtE,cAAc,uCAAuC,CAAC;AACtD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC"}
@@ -29,14 +29,19 @@ export declare class PxParticle extends Particle {
29
29
  vx: number;
30
30
  /** Velocity in pixels per second (Y axis). */
31
31
  vy: number;
32
- /** Angular velocity in radians per second. */
33
- angleV: number;
32
+ /** Base angular velocity in radians per second. */
33
+ private _angleVBase;
34
+ /** Base angular velocity scale for angleVBase */
35
+ private _angleVScale;
34
36
  /**
35
37
  * Optional provider-specific animation state.
36
38
  * Used by AnimatedTextureProvider (if present).
37
39
  */
38
40
  animatedParticleState?: AnimatedParticleState;
39
41
  constructor(options: ParticleOptions);
42
+ set angleVBase(base: number);
43
+ set angleVScale(scale: number);
44
+ get angleV(): number;
40
45
  /**
41
46
  * Resets the particle into pooled (inactive) state.
42
47
  *
@@ -1 +1 @@
1
- {"version":3,"file":"px-particle.d.ts","sourceRoot":"","sources":["../../src/px-particle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAChC,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,qBAAa,UAAW,SAAQ,QAAQ;IACpC,2BAA2B;IACpB,GAAG,SAAK;IAEf,uEAAuE;IAChE,IAAI,SAAK;IAEhB,8CAA8C;IACvC,EAAE,SAAK;IAEd,8CAA8C;IACvC,EAAE,SAAK;IAEd,8CAA8C;IACvC,MAAM,SAAK;IAElB;;;OAGG;IACI,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;gBAEzC,OAAO,EAAE,eAAe;IAWpC;;;;;;;;OAQG;IACI,MAAM,IAAI,IAAI;IAWrB;;;;;;;;OAQG;IACI,OAAO,IAAI,IAAI;CAqBzB"}
1
+ {"version":3,"file":"px-particle.d.ts","sourceRoot":"","sources":["../../src/px-particle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAChC,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,qBAAa,UAAW,SAAQ,QAAQ;IACpC,2BAA2B;IACpB,GAAG,SAAK;IAEf,uEAAuE;IAChE,IAAI,SAAK;IAEhB,8CAA8C;IACvC,EAAE,SAAK;IAEd,8CAA8C;IACvC,EAAE,SAAK;IAEd,mDAAmD;IACnD,OAAO,CAAC,WAAW,CAAK;IAExB,iDAAiD;IACjD,OAAO,CAAC,YAAY,CAAK;IAEzB;;;OAGG;IACI,qBAAqB,CAAC,EAAE,qBAAqB,CAAC;gBAEzC,OAAO,EAAE,eAAe;IAWpC,IAAW,UAAU,CAAC,IAAI,EAAE,MAAM,EAEjC;IAED,IAAW,WAAW,CAAC,KAAK,EAAE,MAAM,EAEnC;IAED,IAAW,MAAM,IAAI,MAAM,CAE1B;IAED;;;;;;;;OAQG;IACI,MAAM,IAAI,IAAI;IAYrB;;;;;;;;OAQG;IACI,OAAO,IAAI,IAAI;CAsBzB"}
@@ -25,11 +25,22 @@ export class PxParticle extends Particle {
25
25
  this.vx = 0;
26
26
  /** Velocity in pixels per second (Y axis). */
27
27
  this.vy = 0;
28
- /** Angular velocity in radians per second. */
29
- this.angleV = 0;
28
+ /** Base angular velocity in radians per second. */
29
+ this._angleVBase = 0;
30
+ /** Base angular velocity scale for angleVBase */
31
+ this._angleVScale = 1;
30
32
  // Start in pooled/inactive state.
31
33
  this.onKill();
32
34
  }
35
+ set angleVBase(base) {
36
+ this._angleVBase = base;
37
+ }
38
+ set angleVScale(scale) {
39
+ this._angleVScale = scale;
40
+ }
41
+ get angleV() {
42
+ return this._angleVBase * this._angleVScale;
43
+ }
33
44
  /**
34
45
  * Resets the particle into pooled (inactive) state.
35
46
  *
@@ -44,7 +55,8 @@ export class PxParticle extends Particle {
44
55
  this.life = 1;
45
56
  this.vx = 0;
46
57
  this.vy = 0;
47
- this.angleV = 0;
58
+ this._angleVBase = 0;
59
+ this._angleVScale = 1;
48
60
  this.animatedParticleState = undefined;
49
61
  }
50
62
  /**
@@ -61,7 +73,8 @@ export class PxParticle extends Particle {
61
73
  this.life = 1;
62
74
  this.vx = 0;
63
75
  this.vy = 0;
64
- this.angleV = 0;
76
+ this._angleVBase = 0;
77
+ this._angleVScale = 1;
65
78
  this.animatedParticleState = undefined;
66
79
  // Reset visual state
67
80
  this.alpha = 1;
@@ -1 +1 @@
1
- {"version":3,"file":"px-particle.js","sourceRoot":"","sources":["../../src/px-particle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,MAAM,SAAS,CAAC;AAYpD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,UAAW,SAAQ,QAAQ;IAsBpC,YAAY,OAAwB;QAChC,2BAA2B;QAC3B,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC;QACtB,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC;QAEtB,KAAK,CAAC,OAAO,CAAC,CAAC;QA1BnB,2BAA2B;QACpB,QAAG,GAAG,CAAC,CAAC;QAEf,uEAAuE;QAChE,SAAI,GAAG,CAAC,CAAC;QAEhB,8CAA8C;QACvC,OAAE,GAAG,CAAC,CAAC;QAEd,8CAA8C;QACvC,OAAE,GAAG,CAAC,CAAC;QAEd,8CAA8C;QACvC,WAAM,GAAG,CAAC,CAAC;QAed,kCAAkC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM;QACT,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAEd,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhB,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAC3C,CAAC;IAED;;;;;;;;OAQG;IACI,OAAO;QACV,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAEd,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhB,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;QAEvC,qBAAqB;QACrB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;QAErB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;CACJ"}
1
+ {"version":3,"file":"px-particle.js","sourceRoot":"","sources":["../../src/px-particle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAmB,MAAM,SAAS,CAAC;AAYpD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,UAAW,SAAQ,QAAQ;IAyBpC,YAAY,OAAwB;QAChC,2BAA2B;QAC3B,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC;QACtB,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC;QAEtB,KAAK,CAAC,OAAO,CAAC,CAAC;QA7BnB,2BAA2B;QACpB,QAAG,GAAG,CAAC,CAAC;QAEf,uEAAuE;QAChE,SAAI,GAAG,CAAC,CAAC;QAEhB,8CAA8C;QACvC,OAAE,GAAG,CAAC,CAAC;QAEd,8CAA8C;QACvC,OAAE,GAAG,CAAC,CAAC;QAEd,mDAAmD;QAC3C,gBAAW,GAAG,CAAC,CAAC;QAExB,iDAAiD;QACzC,iBAAY,GAAG,CAAC,CAAC;QAerB,kCAAkC;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;IAClB,CAAC;IAED,IAAW,UAAU,CAAC,IAAY;QAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAW,WAAW,CAAC,KAAa;QAChC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,IAAW,MAAM;QACb,OAAO,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;IAChD,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM;QACT,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAEd,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAEtB,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;IAC3C,CAAC;IAED;;;;;;;;OAQG;IACI,OAAO;QACV,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAEd,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACZ,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAEtB,IAAI,CAAC,qBAAqB,GAAG,SAAS,CAAC;QAEvC,qBAAqB;QACrB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;QAErB,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAChB,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QAEhB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACX,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;CACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixi-particles-engine",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "High-performance PixiJS v8 particle engine with behaviours and pooling",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -0,0 +1,32 @@
1
+ import { Behaviour } from "../behaviour";
2
+ import { PxParticle } from "../px-particle";
3
+ import { CurveKeyframe, CurveOptions } from "./curved-behaviour/curve-key-frame";
4
+ import { Curve } from "./curved-behaviour/curve-sampler";
5
+ import { Emitter } from "../emitter";
6
+
7
+ /**
8
+ * Rotation over lifetime driven by a curve.
9
+ *
10
+ * Keyframes are sampled using normalized lifetime t in [0..1].
11
+ * Output is clamped to [0..1].
12
+ */
13
+ export class RotationCurveBehaviour implements Behaviour {
14
+ public readonly requires = { color: true };
15
+
16
+ public readonly priority = 50;
17
+
18
+ private curve: Curve;
19
+
20
+ constructor(keyframes: CurveKeyframe[], opts?: CurveOptions) {
21
+ this.curve = new Curve(keyframes);
22
+ }
23
+
24
+ public onSpawn(p: PxParticle) {
25
+ p.angleVScale = this.curve.sample(0);
26
+ }
27
+
28
+ public update(p: PxParticle, _dt?: number, _emitter?: Emitter) {
29
+ const t = p.life > 0 ? p.age / p.life : 1;
30
+ p.angleVScale = this.curve.sample(t);
31
+ }
32
+ }
@@ -2,21 +2,34 @@ import { PxParticle } from "../../px-particle";
2
2
  import { Behaviour } from "../../behaviour";
3
3
 
4
4
  /**
5
- * Spawns particles uniformly within a circle centered at (0, 0).
5
+ * Spawns particles inside a circular ring centered at (0, 0).
6
6
  *
7
- * Uses sqrt(random) to achieve uniform distribution by area
8
- * (without sqrt you'd get clustering toward the center).
7
+ * Outer radius:
8
+ * radius
9
9
  *
10
+ * Inner empty radius:
11
+ * innerRadius
12
+ *
13
+ * Particles spawn only between the outer and inner circles.
14
+ *
15
+ * Uses sqrt(random) to maintain uniform area distribution.
10
16
  */
11
17
  export class CircleSpawnBehaviour implements Behaviour {
12
18
  public readonly priority = -100;
13
19
 
14
- constructor(private readonly radius: number) {}
20
+ constructor(
21
+ public radius: number,
22
+ public innerRadius: number = 0,
23
+ ) {}
15
24
 
16
25
  public onSpawn(p: PxParticle) {
17
26
  const angle = Math.random() * Math.PI * 2;
18
27
 
19
- const r = Math.sqrt(Math.random()) * this.radius;
28
+ const outerR2 = this.radius * this.radius;
29
+ const innerR2 = this.innerRadius * this.innerRadius;
30
+
31
+ // Uniform distribution across ring area
32
+ const r = Math.sqrt(innerR2 + Math.random() * (outerR2 - innerR2));
20
33
 
21
34
  p.x = Math.cos(angle) * r;
22
35
  p.y = Math.sin(angle) * r;
@@ -2,22 +2,55 @@ import { PxParticle } from "../../px-particle";
2
2
  import { Behaviour } from "../../behaviour";
3
3
 
4
4
  /**
5
- * Spawns particles uniformly inside a rectangle centered at (0, 0).
6
- * */
5
+ * Spawns particles inside a rectangular border/ring centered at (0, 0).
6
+ *
7
+ * Outer size:
8
+ * width x height
9
+ *
10
+ * Inner empty area:
11
+ * innerWidth x innerHeight
12
+ *
13
+ * Particles spawn only in the area between the outer and inner rectangles.
14
+ */
7
15
  export class RectangleSpawnBehaviour implements Behaviour {
8
16
  public readonly priority = -100;
9
17
 
10
18
  constructor(
11
- private readonly width: number,
12
- private readonly height: number,
19
+ public width: number,
20
+ public height: number,
21
+
22
+ // Optional inner empty rectangle
23
+ public innerWidth: number = 0,
24
+ public innerHeight: number = 0,
13
25
  ) {}
14
26
 
15
27
  public onSpawn(p: PxParticle) {
16
- const hw = this.width * 0.5;
17
- const hh = this.height * 0.5;
28
+ const outerHW = this.width * 0.5;
29
+ const outerHH = this.height * 0.5;
30
+
31
+ const innerHW = this.innerWidth * 0.5;
32
+ const innerHH = this.innerHeight * 0.5;
33
+
34
+ // No inner hole -> normal rectangle spawn
35
+ if (this.innerWidth <= 0 || this.innerHeight <= 0) {
36
+ p.x = this.rand(-outerHW, outerHW);
37
+ p.y = this.rand(-outerHH, outerHH);
38
+ return;
39
+ }
40
+
41
+ // Pick a random point until it lands outside the inner rectangle
42
+ while (true) {
43
+ const x = this.rand(-outerHW, outerHW);
44
+ const y = this.rand(-outerHH, outerHH);
45
+
46
+ const insideInner = x > -innerHW && x < innerHW && y > -innerHH && y < innerHH;
18
47
 
19
- p.x = this.rand(-hw, hw);
20
- p.y = this.rand(-hh, hh);
48
+ if (!insideInner) {
49
+ p.x = x;
50
+ p.y = y;
51
+ return;
52
+ }
53
+ }
21
54
  }
22
55
 
23
56
  /** Inclusive-exclusive uniform random. */
@@ -5,8 +5,21 @@ import { PxParticle } from "../../px-particle";
5
5
  * Sets a particle's angular velocity at spawn time.
6
6
  *
7
7
  * Does NOT modify rotation per frame directly.
8
- * Instead, it initializes `angleV`, which the emitter integrates each tick.
8
+ * Instead, it initializes `angleVBase`, which the emitter integrates each tick.
9
9
  *
10
+ * Supports:
11
+ *
12
+ * - Fixed value:
13
+ * 2
14
+ *
15
+ * - Random range:
16
+ * { min: -3, max: 3 }
17
+ *
18
+ * - Random range with minimum absolute magnitude:
19
+ * { min: -3, max: 3, minAbs: 2 }
20
+ *
21
+ * Result:
22
+ * [-3 .. -2] U [2 .. 3]
10
23
  */
11
24
  export class StaticRotationBehaviour implements Behaviour {
12
25
  public readonly priority = -60;
@@ -15,14 +28,72 @@ export class StaticRotationBehaviour implements Behaviour {
15
28
 
16
29
  /**
17
30
  * @param speed
18
- * - number → fixed angular velocity (radians/sec)
19
- * - {min,max} → randomized angular velocity per particle
31
+ * - number → fixed angular velocity
32
+ * - object → randomized angular velocity
20
33
  */
21
- constructor(public speed: number | { min: number; max: number }) {}
34
+ constructor(
35
+ public speed:
36
+ | number
37
+ | {
38
+ min: number;
39
+ max: number;
40
+
41
+ /**
42
+ * Optional minimum absolute value.
43
+ *
44
+ * Example:
45
+ * min=-3
46
+ * max=3
47
+ * minAbs=2
48
+ *
49
+ * Produces:
50
+ * [-3..-2] U [2..3]
51
+ */
52
+ minAbs?: number;
53
+ },
54
+ ) {}
22
55
 
23
56
  public onSpawn(p: PxParticle) {
24
- const s = typeof this.speed === "number" ? this.speed : this.speed.min + Math.random() * (this.speed.max - this.speed.min);
57
+ const s = typeof this.speed === "number" ? this.speed : this.randomRange(this.speed.min, this.speed.max, this.speed.minAbs);
58
+
59
+ p.angleVBase = s;
60
+ }
61
+
62
+ private randomRange(min: number, max: number, minAbs?: number): number {
63
+ // Normal range
64
+ if (minAbs == null || minAbs <= 0) {
65
+ return min + Math.random() * (max - min);
66
+ }
67
+
68
+ // If the excluded center does not intersect range,
69
+ // fallback to normal random
70
+ if (min >= minAbs || max <= -minAbs) {
71
+ return min + Math.random() * (max - min);
72
+ }
73
+
74
+ const leftMin = min;
75
+ const leftMax = Math.min(-minAbs, max);
76
+
77
+ const rightMin = Math.max(minAbs, min);
78
+ const rightMax = max;
79
+
80
+ const leftSize = Math.max(0, leftMax - leftMin);
81
+ const rightSize = Math.max(0, rightMax - rightMin);
82
+
83
+ const total = leftSize + rightSize;
84
+
85
+ if (total <= 0) {
86
+ return 0;
87
+ }
88
+
89
+ const pick = Math.random() * total;
90
+
91
+ // Left segment
92
+ if (pick < leftSize) {
93
+ return leftMin + Math.random() * leftSize;
94
+ }
25
95
 
26
- p.angleV = s;
96
+ // Right segment
97
+ return rightMin + Math.random() * rightSize;
27
98
  }
28
99
  }
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ export * from "./behaviours/spawn-behaviours/circle-spawn-behaviour";
13
13
  export * from "./behaviours/spawn-behaviours/rectangle-spawn-behaviour";
14
14
  export * from "./behaviours/static-behaviours/static-rotation-behaviour";
15
15
  export * from "./behaviours/static-behaviours/static-scale-behaviour";
16
+ export * from "./behaviours/rotation-curve-behaviour";
16
17
  export * from "./texture-providers/animated-texture-provider";
17
18
  export * from "./texture-providers/single-texture-provider";
18
19
  export * from "./texture-providers/weighted-texture-provider";