pixi-particles-engine 0.1.8 → 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.
- package/dist/cjs/behaviours/rotation-curve-behaviour.d.ts +21 -0
- package/dist/cjs/behaviours/rotation-curve-behaviour.d.ts.map +1 -0
- package/dist/cjs/behaviours/rotation-curve-behaviour.js +26 -0
- package/dist/cjs/behaviours/rotation-curve-behaviour.js.map +1 -0
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts +12 -5
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts.map +1 -1
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.js +15 -5
- package/dist/cjs/behaviours/spawn-behaviours/circle-spawn-behaviour.js.map +1 -1
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts +15 -5
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts.map +1 -1
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js +36 -7
- package/dist/cjs/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js.map +1 -1
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.d.ts +41 -3
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.d.ts.map +1 -1
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.js +46 -5
- package/dist/cjs/behaviours/static-behaviours/static-rotation-behaviour.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/px-particle.d.ts +7 -2
- package/dist/cjs/px-particle.d.ts.map +1 -1
- package/dist/cjs/px-particle.js +17 -4
- package/dist/cjs/px-particle.js.map +1 -1
- package/dist/esm/behaviours/rotation-curve-behaviour.d.ts +21 -0
- package/dist/esm/behaviours/rotation-curve-behaviour.d.ts.map +1 -0
- package/dist/esm/behaviours/rotation-curve-behaviour.js +22 -0
- package/dist/esm/behaviours/rotation-curve-behaviour.js.map +1 -0
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts +12 -5
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.d.ts.map +1 -1
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.js +15 -5
- package/dist/esm/behaviours/spawn-behaviours/circle-spawn-behaviour.js.map +1 -1
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts +15 -5
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.d.ts.map +1 -1
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js +36 -7
- package/dist/esm/behaviours/spawn-behaviours/rectangle-spawn-behaviour.js.map +1 -1
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.d.ts +41 -3
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.d.ts.map +1 -1
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.js +46 -5
- package/dist/esm/behaviours/static-behaviours/static-rotation-behaviour.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/px-particle.d.ts +7 -2
- package/dist/esm/px-particle.d.ts.map +1 -1
- package/dist/esm/px-particle.js +17 -4
- package/dist/esm/px-particle.js.map +1 -1
- package/package.json +2 -1
- package/src/behaviour.ts +74 -0
- package/src/behaviours/alpha-behaviour.ts +29 -0
- package/src/behaviours/alpha-curve-behaviour.ts +34 -0
- package/src/behaviours/curved-behaviour/curve-key-frame.ts +23 -0
- package/src/behaviours/curved-behaviour/curve-sampler.ts +92 -0
- package/src/behaviours/movement-behaviours/gravity-behaviour.ts +48 -0
- package/src/behaviours/movement-behaviours/movement-curve-behaviour.ts +39 -0
- package/src/behaviours/movement-behaviours/radial-burst-behaviour.ts +57 -0
- package/src/behaviours/rotation-curve-behaviour.ts +32 -0
- package/src/behaviours/scale-curve-behaviour.ts +36 -0
- package/src/behaviours/spawn-behaviours/circle-spawn-behaviour.ts +37 -0
- package/src/behaviours/spawn-behaviours/rectangle-spawn-behaviour.ts +60 -0
- package/src/behaviours/static-behaviours/static-rotation-behaviour.ts +99 -0
- package/src/behaviours/static-behaviours/static-scale-behaviour.ts +21 -0
- package/src/emitter.ts +517 -0
- package/src/index.ts +19 -0
- package/src/px-particle.ts +125 -0
- package/src/texture-provider.ts +66 -0
- package/src/texture-providers/animated-texture-provider.ts +146 -0
- package/src/texture-providers/single-texture-provider.ts +22 -0
- package/src/texture-providers/weighted-texture-provider.ts +52 -0
- package/src/utils.ts +13 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"circle-spawn-behaviour.js","sourceRoot":"","sources":["../../../../src/behaviours/spawn-behaviours/circle-spawn-behaviour.ts"],"names":[],"mappings":"AAGA
|
|
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
|
|
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
|
-
|
|
8
|
-
|
|
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
|
|
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
|
|
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
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
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
|
|
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 `
|
|
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
|
|
22
|
-
* -
|
|
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
|
|
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 `
|
|
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
|
|
12
|
-
* -
|
|
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
|
|
21
|
-
p.
|
|
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
|
|
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"}
|
package/dist/esm/index.d.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";
|
package/dist/esm/index.d.ts.map
CHANGED
|
@@ -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";
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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
|
-
/**
|
|
33
|
-
|
|
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,
|
|
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"}
|
package/dist/esm/px-particle.js
CHANGED
|
@@ -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
|
-
/**
|
|
29
|
-
this.
|
|
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.
|
|
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.
|
|
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;
|
|
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.
|
|
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": {
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
34
|
+
"src",
|
|
34
35
|
"README.md",
|
|
35
36
|
"LICENSE"
|
|
36
37
|
],
|
package/src/behaviour.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { ParticleProperties } from "pixi.js";
|
|
2
|
+
import { Emitter } from "./emitter";
|
|
3
|
+
import { PxParticle } from "./px-particle";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A Behaviour is a modular unit of particle logic.
|
|
7
|
+
*
|
|
8
|
+
* Behaviours can:
|
|
9
|
+
* - Initialize particle state at spawn (velocity, alpha, scale, etc)
|
|
10
|
+
* - Update particle state each frame (curves, gravity, drag, color fade, etc)
|
|
11
|
+
* - Clean up any per-particle state when the particle is recycled
|
|
12
|
+
*
|
|
13
|
+
* Lifecycle:
|
|
14
|
+
* - init(emitter) is called once when the behaviour is added to an emitter
|
|
15
|
+
* - onSpawn(p, emitter) is called each time a particle is spawned
|
|
16
|
+
* - update(p, dt, emitter) is called every frame for each active particle
|
|
17
|
+
* - onKill(p, emitter) is called when a particle dies and returns to the pool
|
|
18
|
+
*/
|
|
19
|
+
export interface Behaviour {
|
|
20
|
+
/**
|
|
21
|
+
* Execution order relative to other behaviours.
|
|
22
|
+
*
|
|
23
|
+
* Lower priority runs earlier.
|
|
24
|
+
* When priorities are equal, execution order is stable and follows registration order.
|
|
25
|
+
*
|
|
26
|
+
* Use priority to ensure correct ordering when behaviours depend on each other
|
|
27
|
+
* (e.g. apply movement first, then apply alpha/scale curves).
|
|
28
|
+
*/
|
|
29
|
+
readonly priority?: number;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Dynamic property requirements for this behaviour.
|
|
33
|
+
*
|
|
34
|
+
* PixiJS ParticleContainer uses `dynamicProperties` to decide which attributes
|
|
35
|
+
* must be re-uploaded to the GPU each frame.
|
|
36
|
+
*
|
|
37
|
+
* If your behaviour changes a property over time that affects rendering,
|
|
38
|
+
* declare it here so the emitter enables the correct dynamicProperties.
|
|
39
|
+
*
|
|
40
|
+
* Examples:
|
|
41
|
+
* - Changing `alpha` over time → requires: { color: true }
|
|
42
|
+
* - Changing `scaleX/scaleY` over time → may require: { vertex: true } (depends on Pixi internals)
|
|
43
|
+
* - Changing `rotation` over time → requires: { rotation: true }
|
|
44
|
+
*
|
|
45
|
+
* NOTE:
|
|
46
|
+
* If your behaviour only sets values ON SPAWN and never changes them after,
|
|
47
|
+
* you usually do NOT need to require dynamic properties.
|
|
48
|
+
*/
|
|
49
|
+
readonly requires?: ParticleProperties;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Optional: called once when the behaviour is registered on an emitter.
|
|
53
|
+
* Useful for caching references, precomputing curves, or validating options.
|
|
54
|
+
*/
|
|
55
|
+
init?(emitter: Emitter): void;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Optional: called when a particle is spawned (taken from pool and activated).
|
|
59
|
+
* Use this to initialize per-particle state for this behaviour.
|
|
60
|
+
*/
|
|
61
|
+
onSpawn?(p: PxParticle, emitter: Emitter): void;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Optional: called every frame for each active particle.
|
|
65
|
+
* `dt` is delta time in seconds (already clamped by the emitter).
|
|
66
|
+
*/
|
|
67
|
+
update?(p: PxParticle, dt: number, emitter: Emitter): void;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Optional: called when the particle is killed and returned to the pool.
|
|
71
|
+
* Use this to clear any per-particle state allocated by the behaviour.
|
|
72
|
+
*/
|
|
73
|
+
onKill?(p: PxParticle, emitter: Emitter): void;
|
|
74
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { PxParticle } from "../px-particle";
|
|
2
|
+
import { Behaviour } from "../behaviour";
|
|
3
|
+
import { Emitter } from "../emitter";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Linearly fades alpha from startAlpha -> endAlpha over particle lifetime.
|
|
7
|
+
*/
|
|
8
|
+
export class AlphaBehaviour implements Behaviour {
|
|
9
|
+
public readonly requires = { color: true };
|
|
10
|
+
|
|
11
|
+
public readonly priority = 50;
|
|
12
|
+
|
|
13
|
+
public startAlpha = 1;
|
|
14
|
+
public endAlpha = 0;
|
|
15
|
+
|
|
16
|
+
constructor(startAlpha = 1, endAlpha = 0) {
|
|
17
|
+
this.startAlpha = startAlpha;
|
|
18
|
+
this.endAlpha = endAlpha;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public onSpawn(p: PxParticle, _emitter: Emitter): void {
|
|
22
|
+
p.alpha = this.startAlpha;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
public update(p: PxParticle, _dt: number, _emitter: Emitter): void {
|
|
26
|
+
const t = p.life > 0 ? Math.min(1, Math.max(0, p.age / p.life)) : 1;
|
|
27
|
+
p.alpha = this.startAlpha + (this.endAlpha - this.startAlpha) * t;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
* Alpha 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 AlphaCurveBehaviour implements Behaviour {
|
|
14
|
+
/** Alpha changes over time, so ParticleContainer must treat color as dynamic. */
|
|
15
|
+
public readonly requires = { color: true };
|
|
16
|
+
|
|
17
|
+
public readonly priority = 50;
|
|
18
|
+
|
|
19
|
+
private curve: Curve;
|
|
20
|
+
|
|
21
|
+
constructor(keyframes: CurveKeyframe[], opts?: CurveOptions) {
|
|
22
|
+
// Always clamp alpha to [0..1]
|
|
23
|
+
this.curve = new Curve(keyframes, { ...opts, clamp: { min: 0, max: 1 } });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public onSpawn(p: PxParticle) {
|
|
27
|
+
p.alpha = this.curve.sample(0);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public update(p: PxParticle, _dt?: number, _emitter?: Emitter) {
|
|
31
|
+
const t = p.life > 0 ? p.age / p.life : 1;
|
|
32
|
+
p.alpha = this.curve.sample(t);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type EaseFn = (x: number) => number;
|
|
2
|
+
|
|
3
|
+
export type CurveKeyframe = {
|
|
4
|
+
/** Normalized lifetime [0..1]. */
|
|
5
|
+
time: number;
|
|
6
|
+
|
|
7
|
+
/** Value at this time. */
|
|
8
|
+
value: number;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Optional easing applied to the segment starting at this keyframe,
|
|
12
|
+
* i.e. easing used for interpolation from this keyframe -> next keyframe.
|
|
13
|
+
*/
|
|
14
|
+
ease?: EaseFn;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type CurveOptions = {
|
|
18
|
+
/** Default easing used when a segment has no per-keyframe ease. */
|
|
19
|
+
defaultEase?: EaseFn;
|
|
20
|
+
|
|
21
|
+
/** Optional clamp on sampled output. */
|
|
22
|
+
clamp?: { min: number; max: number };
|
|
23
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Utils } from "../../utils";
|
|
2
|
+
import { CurveKeyframe, EaseFn, CurveOptions } from "./curve-key-frame";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Lightweight curve sampler for keyframed 1D values over normalized time [0..1].
|
|
6
|
+
*
|
|
7
|
+
* - Keyframes are clamped to [0..1] and sorted by time.
|
|
8
|
+
* - Endpoints at t=0 and t=1 are ensured (added if missing).
|
|
9
|
+
* - Each segment can have its own easing function.
|
|
10
|
+
*/
|
|
11
|
+
export class Curve {
|
|
12
|
+
/** Cleaned + sorted keyframes (always includes endpoints at 0 and 1). */
|
|
13
|
+
private keys: CurveKeyframe[];
|
|
14
|
+
|
|
15
|
+
/** Default easing used when the keyframe has no `ease`. */
|
|
16
|
+
private defaultEase?: EaseFn;
|
|
17
|
+
|
|
18
|
+
/** Optional output clamp. */
|
|
19
|
+
private clamp?: { min: number; max: number };
|
|
20
|
+
|
|
21
|
+
constructor(keyframes: CurveKeyframe[], opts?: CurveOptions) {
|
|
22
|
+
this.defaultEase = opts?.defaultEase;
|
|
23
|
+
this.clamp = opts?.clamp;
|
|
24
|
+
|
|
25
|
+
// Normalize and sort keyframes.
|
|
26
|
+
const cleaned: CurveKeyframe[] = (keyframes ?? [])
|
|
27
|
+
.map((k) => ({
|
|
28
|
+
time: Utils.clamp01(k.time),
|
|
29
|
+
value: k.value,
|
|
30
|
+
ease: k.ease,
|
|
31
|
+
}))
|
|
32
|
+
.sort((a, b) => a.time - b.time);
|
|
33
|
+
|
|
34
|
+
// Fallback: flat zero curve.
|
|
35
|
+
if (cleaned.length === 0) cleaned.push({ time: 0, value: 0 }, { time: 1, value: 0 });
|
|
36
|
+
|
|
37
|
+
// Ensure endpoints exist at t=0 and t=1.
|
|
38
|
+
if (cleaned[0].time !== 0) cleaned.unshift({ time: 0, value: cleaned[0].value });
|
|
39
|
+
|
|
40
|
+
if (cleaned[cleaned.length - 1].time !== 1)
|
|
41
|
+
cleaned.push({
|
|
42
|
+
time: 1,
|
|
43
|
+
value: cleaned[cleaned.length - 1].value,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.keys = cleaned;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Samples the curve at normalized time t01.
|
|
51
|
+
* Input is clamped to [0..1].
|
|
52
|
+
*/
|
|
53
|
+
public sample(t01: number): number {
|
|
54
|
+
const t = Utils.clamp01(t01);
|
|
55
|
+
|
|
56
|
+
// Find which segment [k0..k1] contains t.
|
|
57
|
+
const i = this.findSegmentIndex(t);
|
|
58
|
+
const k0 = this.keys[i];
|
|
59
|
+
const k1 = this.keys[i + 1];
|
|
60
|
+
|
|
61
|
+
const span = k1.time - k0.time;
|
|
62
|
+
if (span <= 0) return this.clampValue(k1.value);
|
|
63
|
+
|
|
64
|
+
// Normalize t into segment space [0..1].
|
|
65
|
+
let u = (t - k0.time) / span;
|
|
66
|
+
u = Utils.clamp01(u);
|
|
67
|
+
|
|
68
|
+
// Apply easing for this segment (if any).
|
|
69
|
+
const ease = k0.ease ?? this.defaultEase;
|
|
70
|
+
if (ease) u = Utils.clamp01(ease(u));
|
|
71
|
+
|
|
72
|
+
// Linear interpolation between segment endpoints.
|
|
73
|
+
const v = Utils.lerp(k0.value, k1.value, u);
|
|
74
|
+
return this.clampValue(v);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Finds the segment index i such that t is between keys[i] and keys[i+1].
|
|
79
|
+
*/
|
|
80
|
+
private findSegmentIndex(t: number): number {
|
|
81
|
+
for (let i = 0; i < this.keys.length - 2; i++) {
|
|
82
|
+
if (t <= this.keys[i + 1].time) return i;
|
|
83
|
+
}
|
|
84
|
+
return this.keys.length - 2;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Applies optional output clamp. */
|
|
88
|
+
private clampValue(v: number): number {
|
|
89
|
+
if (!this.clamp) return v;
|
|
90
|
+
return Math.min(this.clamp.max, Math.max(this.clamp.min, v));
|
|
91
|
+
}
|
|
92
|
+
}
|