custom-pixi-particles 4.40.1 → 4.41.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.
- package/dist/lib/behaviour/TemperatureBehaviour.d.ts +37 -30
- package/dist/lib/behaviour/TemperatureBehaviour.js +180 -30
- package/dist/lib/behaviour/TemperatureBehaviour.js.map +1 -1
- package/dist/lib/behaviour/ToroidalWrapBehaviour.d.ts +6 -4
- package/dist/lib/behaviour/ToroidalWrapBehaviour.js +16 -28
- package/dist/lib/behaviour/ToroidalWrapBehaviour.js.map +1 -1
- package/dist/lib/util/toroidalWrapExtents.d.ts +22 -0
- package/dist/lib/util/toroidalWrapExtents.js +55 -0
- package/dist/lib/util/toroidalWrapExtents.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,47 +1,54 @@
|
|
|
1
1
|
import Behaviour from './Behaviour';
|
|
2
2
|
import Particle from '../Particle';
|
|
3
3
|
import { Color, Point } from '../util';
|
|
4
|
+
export type TemperatureZoneShapeType = 'circle' | 'square' | 'rectangle';
|
|
5
|
+
export type TemperatureZone = {
|
|
6
|
+
center: Point;
|
|
7
|
+
velocity: Point;
|
|
8
|
+
color: Color;
|
|
9
|
+
shapeType?: TemperatureZoneShapeType;
|
|
10
|
+
radius?: number;
|
|
11
|
+
halfSize?: number;
|
|
12
|
+
halfWidth?: number;
|
|
13
|
+
halfHeight?: number;
|
|
14
|
+
};
|
|
4
15
|
/**
|
|
5
16
|
* TemperatureBehaviour adjusts particle velocity and color
|
|
6
17
|
* based on whether they are in a hot or cold zone.
|
|
18
|
+
*
|
|
19
|
+
* Gradual color mode is designed to run after ColorBehaviour (lower priority):
|
|
20
|
+
* ColorBehaviour sets the natural particle color first, then this behaviour
|
|
21
|
+
* blends zone tint on top and eases back to the live natural color on exit.
|
|
7
22
|
*/
|
|
8
23
|
export default class TemperatureBehaviour extends Behaviour {
|
|
9
24
|
enabled: boolean;
|
|
10
25
|
priority: number;
|
|
11
|
-
zones:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}[];
|
|
17
|
-
/**
|
|
18
|
-
* Initializes the particle. This behavior does not require
|
|
19
|
-
* per-particle initialization, but it's included for extensibility.
|
|
20
|
-
*/
|
|
26
|
+
zones: TemperatureZone[];
|
|
27
|
+
/** When true, particle color eases toward zone / outside colors instead of snapping. */
|
|
28
|
+
gradualColorTransition: boolean;
|
|
29
|
+
/** Blend speed toward the target color (higher = faster). */
|
|
30
|
+
colorTransitionSpeed: number;
|
|
21
31
|
init(particle: Particle): void;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
apply(particle: Particle, deltaTime?: number): void;
|
|
33
|
+
private applyGradualOutsideColor;
|
|
34
|
+
private clearGradualColorState;
|
|
35
|
+
private findActiveZone;
|
|
36
|
+
private zoneColor;
|
|
37
|
+
private copyColor;
|
|
38
|
+
private writeColor;
|
|
39
|
+
private mixColors;
|
|
40
|
+
private stepBlendToward;
|
|
41
|
+
private getBlendT;
|
|
42
|
+
private lerp;
|
|
43
|
+
private matchesAnyZoneColor;
|
|
44
|
+
private matchesAnyZoneColorValue;
|
|
45
|
+
isInZone(particle: Particle, zone: TemperatureZone): boolean;
|
|
33
46
|
getName(): string;
|
|
34
|
-
/**
|
|
35
|
-
* Returns properties for serialization or debugging.
|
|
36
|
-
*/
|
|
37
47
|
getProps(): {
|
|
38
48
|
enabled: boolean;
|
|
39
49
|
priority: number;
|
|
40
|
-
zones:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
velocity: Point;
|
|
44
|
-
color: Color;
|
|
45
|
-
}[];
|
|
50
|
+
zones: TemperatureZone[];
|
|
51
|
+
gradualColorTransition: boolean;
|
|
52
|
+
colorTransitionSpeed: number;
|
|
46
53
|
};
|
|
47
54
|
}
|
|
@@ -3,61 +3,211 @@ import behaviourNames from './BehaviourNames';
|
|
|
3
3
|
/**
|
|
4
4
|
* TemperatureBehaviour adjusts particle velocity and color
|
|
5
5
|
* based on whether they are in a hot or cold zone.
|
|
6
|
+
*
|
|
7
|
+
* Gradual color mode is designed to run after ColorBehaviour (lower priority):
|
|
8
|
+
* ColorBehaviour sets the natural particle color first, then this behaviour
|
|
9
|
+
* blends zone tint on top and eases back to the live natural color on exit.
|
|
6
10
|
*/
|
|
7
11
|
export default class TemperatureBehaviour extends Behaviour {
|
|
8
12
|
constructor() {
|
|
9
13
|
super(...arguments);
|
|
10
14
|
this.enabled = true;
|
|
11
|
-
this.priority =
|
|
15
|
+
this.priority = 50;
|
|
12
16
|
this.zones = [];
|
|
17
|
+
/** When true, particle color eases toward zone / outside colors instead of snapping. */
|
|
18
|
+
this.gradualColorTransition = false;
|
|
19
|
+
/** Blend speed toward the target color (higher = faster). */
|
|
20
|
+
this.colorTransitionSpeed = 6;
|
|
13
21
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Initializes the particle. This behavior does not require
|
|
16
|
-
* per-particle initialization, but it's included for extensibility.
|
|
17
|
-
*/
|
|
18
22
|
init(particle) {
|
|
19
|
-
|
|
23
|
+
const p = particle;
|
|
24
|
+
p._temperatureInZone = false;
|
|
25
|
+
p._temperatureTransitioningOut = false;
|
|
26
|
+
p._temperatureBlend = 0;
|
|
27
|
+
p._temperatureOutsideColor = null;
|
|
28
|
+
p._temperatureLastZoneColor = null;
|
|
20
29
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
*/
|
|
24
|
-
apply(particle) {
|
|
30
|
+
apply(particle, deltaTime = 1 / 60) {
|
|
31
|
+
var _a, _b, _c;
|
|
25
32
|
if (!this.enabled || !this.zones || !this.zones.length)
|
|
26
33
|
return;
|
|
27
|
-
|
|
34
|
+
const p = particle;
|
|
35
|
+
const activeZone = this.findActiveZone(particle);
|
|
36
|
+
const naturalColor = this.copyColor(particle);
|
|
37
|
+
const wasInZone = p._temperatureInZone === true;
|
|
38
|
+
if (!activeZone) {
|
|
39
|
+
if (this.gradualColorTransition) {
|
|
40
|
+
if (wasInZone) {
|
|
41
|
+
p._temperatureTransitioningOut = true;
|
|
42
|
+
}
|
|
43
|
+
this.applyGradualOutsideColor(particle, p, naturalColor, deltaTime);
|
|
44
|
+
}
|
|
45
|
+
else if (wasInZone && p._temperatureOutsideColor && this.matchesAnyZoneColor(particle)) {
|
|
46
|
+
this.writeColor(particle, p._temperatureOutsideColor);
|
|
47
|
+
}
|
|
48
|
+
else if (!wasInZone) {
|
|
49
|
+
p._temperatureOutsideColor = naturalColor;
|
|
50
|
+
}
|
|
51
|
+
p._temperatureInZone = false;
|
|
52
|
+
if (!this.gradualColorTransition) {
|
|
53
|
+
this.clearGradualColorState(particle, p);
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (this.gradualColorTransition) {
|
|
58
|
+
p._temperatureTransitioningOut = false;
|
|
59
|
+
if (!wasInZone || !p._temperatureOutsideColor) {
|
|
60
|
+
p._temperatureOutsideColor = naturalColor;
|
|
61
|
+
}
|
|
62
|
+
if (!wasInZone && ((_a = p._temperatureBlend) !== null && _a !== void 0 ? _a : 0) <= 0) {
|
|
63
|
+
p._temperatureBlend = 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (!wasInZone) {
|
|
67
|
+
p._temperatureOutsideColor = naturalColor;
|
|
68
|
+
}
|
|
69
|
+
particle.velocity.x *= activeZone.velocity.x;
|
|
70
|
+
particle.velocity.y *= activeZone.velocity.y;
|
|
71
|
+
const zoneColor = this.zoneColor(activeZone);
|
|
72
|
+
p._temperatureLastZoneColor = zoneColor;
|
|
73
|
+
if (this.gradualColorTransition) {
|
|
74
|
+
const blend = this.stepBlendToward((_b = p._temperatureBlend) !== null && _b !== void 0 ? _b : 0, 1, deltaTime);
|
|
75
|
+
p._temperatureBlend = blend;
|
|
76
|
+
const outside = (_c = p._temperatureOutsideColor) !== null && _c !== void 0 ? _c : naturalColor;
|
|
77
|
+
this.writeColor(particle, this.mixColors(outside, zoneColor, blend));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
this.writeColor(particle, zoneColor);
|
|
81
|
+
p._temperatureBlend = 1;
|
|
82
|
+
}
|
|
83
|
+
p._temperatureInZone = true;
|
|
84
|
+
}
|
|
85
|
+
applyGradualOutsideColor(particle, p, naturalColor, deltaTime) {
|
|
86
|
+
var _a, _b, _c, _d;
|
|
87
|
+
const transitioningOut = p._temperatureTransitioningOut === true;
|
|
88
|
+
const startBlend = transitioningOut ? ((_a = p._temperatureBlend) !== null && _a !== void 0 ? _a : 1) : ((_b = p._temperatureBlend) !== null && _b !== void 0 ? _b : 0);
|
|
89
|
+
if (!transitioningOut && !this.matchesAnyZoneColorValue(naturalColor)) {
|
|
90
|
+
p._temperatureOutsideColor = naturalColor;
|
|
91
|
+
}
|
|
92
|
+
const blend = this.stepBlendToward(startBlend, 0, deltaTime);
|
|
93
|
+
p._temperatureBlend = blend;
|
|
94
|
+
if (!transitioningOut && blend <= 0.001) {
|
|
95
|
+
p._temperatureBlend = 0;
|
|
96
|
+
p._temperatureTransitioningOut = false;
|
|
97
|
+
p._temperatureLastZoneColor = null;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const outside = transitioningOut
|
|
101
|
+
? naturalColor
|
|
102
|
+
: ((_c = p._temperatureOutsideColor) !== null && _c !== void 0 ? _c : naturalColor);
|
|
103
|
+
const zone = (_d = p._temperatureLastZoneColor) !== null && _d !== void 0 ? _d : outside;
|
|
104
|
+
this.writeColor(particle, this.mixColors(outside, zone, blend));
|
|
105
|
+
if (blend <= 0.001) {
|
|
106
|
+
p._temperatureBlend = 0;
|
|
107
|
+
p._temperatureTransitioningOut = false;
|
|
108
|
+
p._temperatureLastZoneColor = null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
clearGradualColorState(particle, p) {
|
|
112
|
+
p._temperatureBlend = 0;
|
|
113
|
+
p._temperatureLastZoneColor = null;
|
|
114
|
+
}
|
|
115
|
+
findActiveZone(particle) {
|
|
28
116
|
for (const zone of this.zones) {
|
|
29
|
-
if (this.isInZone(particle, zone
|
|
30
|
-
|
|
31
|
-
particle.velocity.y *= zone.velocity.y;
|
|
32
|
-
particle.color.r = zone.color.r;
|
|
33
|
-
particle.color.g = zone.color.g;
|
|
34
|
-
particle.color.b = zone.color.b;
|
|
35
|
-
break;
|
|
117
|
+
if (this.isInZone(particle, zone)) {
|
|
118
|
+
return zone;
|
|
36
119
|
}
|
|
37
120
|
}
|
|
121
|
+
return null;
|
|
38
122
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
123
|
+
zoneColor(zone) {
|
|
124
|
+
var _a;
|
|
125
|
+
return {
|
|
126
|
+
r: zone.color.r,
|
|
127
|
+
g: zone.color.g,
|
|
128
|
+
b: zone.color.b,
|
|
129
|
+
alpha: (_a = zone.color.alpha) !== null && _a !== void 0 ? _a : 1,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
copyColor(particle) {
|
|
133
|
+
return {
|
|
134
|
+
r: particle.color.r,
|
|
135
|
+
g: particle.color.g,
|
|
136
|
+
b: particle.color.b,
|
|
137
|
+
alpha: particle.color.alpha,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
writeColor(particle, color) {
|
|
141
|
+
particle.color.r = color.r;
|
|
142
|
+
particle.color.g = color.g;
|
|
143
|
+
particle.color.b = color.b;
|
|
144
|
+
particle.color.alpha = color.alpha;
|
|
145
|
+
}
|
|
146
|
+
mixColors(from, to, blend) {
|
|
147
|
+
const t = Math.max(0, Math.min(1, blend));
|
|
148
|
+
return {
|
|
149
|
+
r: this.lerp(from.r, to.r, t),
|
|
150
|
+
g: this.lerp(from.g, to.g, t),
|
|
151
|
+
b: this.lerp(from.b, to.b, t),
|
|
152
|
+
alpha: this.lerp(from.alpha, to.alpha, t),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
stepBlendToward(current, target, deltaTime) {
|
|
156
|
+
const t = this.getBlendT(deltaTime);
|
|
157
|
+
const next = current + (target - current) * t;
|
|
158
|
+
if (target > current)
|
|
159
|
+
return Math.min(target, next);
|
|
160
|
+
return Math.max(target, next);
|
|
161
|
+
}
|
|
162
|
+
getBlendT(deltaTime) {
|
|
163
|
+
const speed = Math.max(0, this.colorTransitionSpeed);
|
|
164
|
+
if (speed <= 0)
|
|
165
|
+
return 0;
|
|
166
|
+
const dtSeconds = deltaTime >= 1 ? deltaTime / 60 : deltaTime;
|
|
167
|
+
return 1 - Math.exp(-speed * dtSeconds);
|
|
168
|
+
}
|
|
169
|
+
lerp(start, end, t) {
|
|
170
|
+
return start + (end - start) * t;
|
|
171
|
+
}
|
|
172
|
+
matchesAnyZoneColor(particle) {
|
|
173
|
+
return this.matchesAnyZoneColorValue(this.copyColor(particle));
|
|
174
|
+
}
|
|
175
|
+
matchesAnyZoneColorValue(color) {
|
|
176
|
+
for (const zone of this.zones) {
|
|
177
|
+
const zoneColor = this.zoneColor(zone);
|
|
178
|
+
if (color.r === zoneColor.r && color.g === zoneColor.g && color.b === zoneColor.b) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
isInZone(particle, zone) {
|
|
185
|
+
var _a, _b, _c, _d, _e;
|
|
186
|
+
const dx = particle.movement.x - zone.center.x;
|
|
187
|
+
const dy = particle.movement.y - zone.center.y;
|
|
188
|
+
const shapeType = (_a = zone.shapeType) !== null && _a !== void 0 ? _a : 'circle';
|
|
189
|
+
if (shapeType === 'square') {
|
|
190
|
+
const halfSize = (_b = zone.halfSize) !== null && _b !== void 0 ? _b : 0;
|
|
191
|
+
return Math.abs(dx) < halfSize && Math.abs(dy) < halfSize;
|
|
192
|
+
}
|
|
193
|
+
if (shapeType === 'rectangle') {
|
|
194
|
+
const halfWidth = (_c = zone.halfWidth) !== null && _c !== void 0 ? _c : 0;
|
|
195
|
+
const halfHeight = (_d = zone.halfHeight) !== null && _d !== void 0 ? _d : 0;
|
|
196
|
+
return Math.abs(dx) < halfWidth && Math.abs(dy) < halfHeight;
|
|
197
|
+
}
|
|
198
|
+
const radius = (_e = zone.radius) !== null && _e !== void 0 ? _e : 0;
|
|
45
199
|
return Math.sqrt(dx * dx + dy * dy) < radius;
|
|
46
200
|
}
|
|
47
|
-
/**
|
|
48
|
-
* Returns the name of the behavior.
|
|
49
|
-
*/
|
|
50
201
|
getName() {
|
|
51
202
|
return behaviourNames.TEMPERATURE_BEHAVIOUR;
|
|
52
203
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Returns properties for serialization or debugging.
|
|
55
|
-
*/
|
|
56
204
|
getProps() {
|
|
57
205
|
return {
|
|
58
206
|
enabled: this.enabled,
|
|
59
207
|
priority: this.priority,
|
|
60
208
|
zones: this.zones,
|
|
209
|
+
gradualColorTransition: this.gradualColorTransition,
|
|
210
|
+
colorTransitionSpeed: this.colorTransitionSpeed,
|
|
61
211
|
};
|
|
62
212
|
}
|
|
63
213
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemperatureBehaviour.js","sourceRoot":"","sources":["../../../src/lib/behaviour/TemperatureBehaviour.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,aAAa,CAAA;AAGnC,OAAO,cAAc,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"TemperatureBehaviour.js","sourceRoot":"","sources":["../../../src/lib/behaviour/TemperatureBehaviour.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,aAAa,CAAA;AAGnC,OAAO,cAAc,MAAM,kBAAkB,CAAA;AA8B7C;;;;;;;GAOG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,SAAS;IAA3D;;QACE,YAAO,GAAG,IAAI,CAAA;QACd,aAAQ,GAAG,EAAE,CAAA;QAEb,UAAK,GAAsB,EAAE,CAAA;QAC7B,wFAAwF;QACxF,2BAAsB,GAAG,KAAK,CAAA;QAC9B,6DAA6D;QAC7D,yBAAoB,GAAG,CAAC,CAAA;IA2N1B,CAAC;IAzNC,IAAI,CAAC,QAAkB;QACrB,MAAM,CAAC,GAAG,QAAoC,CAAA;QAC9C,CAAC,CAAC,kBAAkB,GAAG,KAAK,CAAA;QAC5B,CAAC,CAAC,4BAA4B,GAAG,KAAK,CAAA;QACtC,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAA;QACvB,CAAC,CAAC,wBAAwB,GAAG,IAAI,CAAA;QACjC,CAAC,CAAC,yBAAyB,GAAG,IAAI,CAAA;IACpC,CAAC;IAED,KAAK,CAAC,QAAkB,EAAE,SAAS,GAAG,CAAC,GAAG,EAAE;;QAC1C,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAM;QAE9D,MAAM,CAAC,GAAG,QAAoC,CAAA;QAC9C,MAAM,UAAU,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAA;QAChD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAC7C,MAAM,SAAS,GAAG,CAAC,CAAC,kBAAkB,KAAK,IAAI,CAAA;QAE/C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAChC,IAAI,SAAS,EAAE,CAAC;oBACd,CAAC,CAAC,4BAA4B,GAAG,IAAI,CAAA;gBACvC,CAAC;gBACD,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,CAAA;YACrE,CAAC;iBAAM,IAAI,SAAS,IAAI,CAAC,CAAC,wBAAwB,IAAI,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzF,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,wBAAwB,CAAC,CAAA;YACvD,CAAC;iBAAM,IAAI,CAAC,SAAS,EAAE,CAAC;gBACtB,CAAC,CAAC,wBAAwB,GAAG,YAAY,CAAA;YAC3C,CAAC;YAED,CAAC,CAAC,kBAAkB,GAAG,KAAK,CAAA;YAC5B,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBACjC,IAAI,CAAC,sBAAsB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;YAC1C,CAAC;YACD,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,CAAC,CAAC,4BAA4B,GAAG,KAAK,CAAA;YACtC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,wBAAwB,EAAE,CAAC;gBAC9C,CAAC,CAAC,wBAAwB,GAAG,YAAY,CAAA;YAC3C,CAAC;YACD,IAAI,CAAC,SAAS,IAAI,CAAC,MAAA,CAAC,CAAC,iBAAiB,mCAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBAClD,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACtB,CAAC,CAAC,wBAAwB,GAAG,YAAY,CAAA;QAC3C,CAAC;QAED,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;QAC5C,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;QAE5C,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAA;QAC5C,CAAC,CAAC,yBAAyB,GAAG,SAAS,CAAA;QAEvC,IAAI,IAAI,CAAC,sBAAsB,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,MAAA,CAAC,CAAC,iBAAiB,mCAAI,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;YAC1E,CAAC,CAAC,iBAAiB,GAAG,KAAK,CAAA;YAC3B,MAAM,OAAO,GAAG,MAAA,CAAC,CAAC,wBAAwB,mCAAI,YAAY,CAAA;YAC1D,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAA;QACtE,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;YACpC,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAA;QACzB,CAAC;QAED,CAAC,CAAC,kBAAkB,GAAG,IAAI,CAAA;IAC7B,CAAC;IAEO,wBAAwB,CAC9B,QAAkB,EAClB,CAA2B,EAC3B,YAAoC,EACpC,SAAiB;;QAEjB,MAAM,gBAAgB,GAAG,CAAC,CAAC,4BAA4B,KAAK,IAAI,CAAA;QAChE,MAAM,UAAU,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAA,CAAC,CAAC,iBAAiB,mCAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAA,CAAC,CAAC,iBAAiB,mCAAI,CAAC,CAAC,CAAA;QAE7F,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,YAAY,CAAC,EAAE,CAAC;YACtE,CAAC,CAAC,wBAAwB,GAAG,YAAY,CAAA;QAC3C,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;QAC5D,CAAC,CAAC,iBAAiB,GAAG,KAAK,CAAA;QAE3B,IAAI,CAAC,gBAAgB,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;YACxC,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAA;YACvB,CAAC,CAAC,4BAA4B,GAAG,KAAK,CAAA;YACtC,CAAC,CAAC,yBAAyB,GAAG,IAAI,CAAA;YAClC,OAAM;QACR,CAAC;QAED,MAAM,OAAO,GAAG,gBAAgB;YAC9B,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,CAAC,MAAA,CAAC,CAAC,wBAAwB,mCAAI,YAAY,CAAC,CAAA;QAChD,MAAM,IAAI,GAAG,MAAA,CAAC,CAAC,yBAAyB,mCAAI,OAAO,CAAA;QACnD,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAA;QAE/D,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;YACnB,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAA;YACvB,CAAC,CAAC,4BAA4B,GAAG,KAAK,CAAA;YACtC,CAAC,CAAC,yBAAyB,GAAG,IAAI,CAAA;QACpC,CAAC;IACH,CAAC;IAEO,sBAAsB,CAAC,QAAkB,EAAE,CAA2B;QAC5E,CAAC,CAAC,iBAAiB,GAAG,CAAC,CAAA;QACvB,CAAC,CAAC,yBAAyB,GAAG,IAAI,CAAA;IACpC,CAAC;IAEO,cAAc,CAAC,QAAkB;QACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAEO,SAAS,CAAC,IAAqB;;QACrC,OAAO;YACL,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACf,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACf,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;YACf,KAAK,EAAE,MAAA,IAAI,CAAC,KAAK,CAAC,KAAK,mCAAI,CAAC;SAC7B,CAAA;IACH,CAAC;IAEO,SAAS,CAAC,QAAkB;QAClC,OAAO;YACL,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnB,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK;SAC5B,CAAA;IACH,CAAC;IAEO,UAAU,CAAC,QAAkB,EAAE,KAA6B;QAClE,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;QAC1B,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;QAC1B,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;QAC1B,QAAQ,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;IACpC,CAAC;IAEO,SAAS,CAAC,IAA4B,EAAE,EAA0B,EAAE,KAAa;QACvF,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;QACzC,OAAO;YACL,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7B,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;SAC1C,CAAA;IACH,CAAC;IAEO,eAAe,CAAC,OAAe,EAAE,MAAc,EAAE,SAAiB;QACxE,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;QACnC,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;QAC7C,IAAI,MAAM,GAAG,OAAO;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACnD,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAC/B,CAAC;IAEO,SAAS,CAAC,SAAiB;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAA;QACpD,IAAI,KAAK,IAAI,CAAC;YAAE,OAAO,CAAC,CAAA;QACxB,MAAM,SAAS,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QAC7D,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC,CAAA;IACzC,CAAC;IAEO,IAAI,CAAC,KAAa,EAAE,GAAW,EAAE,CAAS;QAChD,OAAO,KAAK,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;IAClC,CAAC;IAEO,mBAAmB,CAAC,QAAkB;QAC5C,OAAO,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAA;IAChE,CAAC;IAEO,wBAAwB,CAAC,KAA6B;QAC5D,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YACtC,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,EAAE,CAAC;gBAClF,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAED,QAAQ,CAAC,QAAkB,EAAE,IAAqB;;QAChD,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QAC9C,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;QAC9C,MAAM,SAAS,GAAG,MAAA,IAAI,CAAC,SAAS,mCAAI,QAAQ,CAAA;QAE5C,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,MAAA,IAAI,CAAC,QAAQ,mCAAI,CAAC,CAAA;YACnC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAA;QAC3D,CAAC;QAED,IAAI,SAAS,KAAK,WAAW,EAAE,CAAC;YAC9B,MAAM,SAAS,GAAG,MAAA,IAAI,CAAC,SAAS,mCAAI,CAAC,CAAA;YACrC,MAAM,UAAU,GAAG,MAAA,IAAI,CAAC,UAAU,mCAAI,CAAC,CAAA;YACvC,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAA;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,MAAA,IAAI,CAAC,MAAM,mCAAI,CAAC,CAAA;QAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAAA;IAC9C,CAAC;IAED,OAAO;QACL,OAAO,cAAc,CAAC,qBAAqB,CAAA;IAC7C,CAAC;IAED,QAAQ;QACN,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;YACnD,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;SAChD,CAAA;IACH,CAAC;CACF"}
|
|
@@ -3,10 +3,12 @@ import Particle from '../Particle';
|
|
|
3
3
|
import type Model from '../Model';
|
|
4
4
|
import type TurbulencePool from '../util/turbulencePool';
|
|
5
5
|
/**
|
|
6
|
-
* Toroidal screen/world wrap: particles that leave an axis-aligned rectangle
|
|
7
|
-
* re-enter on the opposite side
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Toroidal screen/world wrap: particles that fully leave an axis-aligned rectangle
|
|
7
|
+
* re-enter on the opposite side while still fully outside the view (no visible jump).
|
|
8
|
+
* Uses sprite bounds when available; falls back to particle size. Runs after
|
|
9
|
+
* {@link PositionBehaviour} (lower priority). Syncs {@link Particle.movement} with
|
|
10
|
+
* wrapped {@link Particle.x}/{@link Particle.y} (same pattern as {@link BounceBehaviour}).
|
|
11
|
+
* Do not combine with bounce on the same axis.
|
|
10
12
|
*/
|
|
11
13
|
export default class ToroidalWrapBehaviour extends Behaviour {
|
|
12
14
|
enabled: boolean;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import Behaviour from './Behaviour';
|
|
2
2
|
import BehaviourNames from './BehaviourNames';
|
|
3
|
+
import { getToroidalEdgeExtents, wrapToroidalAxis } from '../util/toroidalWrapExtents';
|
|
3
4
|
/**
|
|
4
|
-
* Toroidal screen/world wrap: particles that leave an axis-aligned rectangle
|
|
5
|
-
* re-enter on the opposite side
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Toroidal screen/world wrap: particles that fully leave an axis-aligned rectangle
|
|
6
|
+
* re-enter on the opposite side while still fully outside the view (no visible jump).
|
|
7
|
+
* Uses sprite bounds when available; falls back to particle size. Runs after
|
|
8
|
+
* {@link PositionBehaviour} (lower priority). Syncs {@link Particle.movement} with
|
|
9
|
+
* wrapped {@link Particle.x}/{@link Particle.y} (same pattern as {@link BounceBehaviour}).
|
|
10
|
+
* Do not combine with bounce on the same axis.
|
|
8
11
|
*/
|
|
9
12
|
export default class ToroidalWrapBehaviour extends Behaviour {
|
|
10
13
|
constructor() {
|
|
@@ -36,35 +39,20 @@ export default class ToroidalWrapBehaviour extends Behaviour {
|
|
|
36
39
|
const maxX = base.maxX - this.inset;
|
|
37
40
|
const minY = base.minY + this.inset;
|
|
38
41
|
const maxY = base.maxY - this.inset;
|
|
42
|
+
const extents = getToroidalEdgeExtents(particle);
|
|
39
43
|
let x = particle.x;
|
|
40
44
|
let y = particle.y;
|
|
41
45
|
let mx = particle.movement.x;
|
|
42
46
|
let my = particle.movement.y;
|
|
43
|
-
if (this.wrapX) {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
x += w;
|
|
48
|
-
mx += w;
|
|
49
|
-
}
|
|
50
|
-
while (x > maxX) {
|
|
51
|
-
x -= w;
|
|
52
|
-
mx -= w;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
47
|
+
if (this.wrapX && maxX > minX) {
|
|
48
|
+
const wrapped = wrapToroidalAxis(x, mx, minX, maxX, extents.left, extents.right, particle.velocity.x);
|
|
49
|
+
x = wrapped.position;
|
|
50
|
+
mx = wrapped.movement;
|
|
55
51
|
}
|
|
56
|
-
if (this.wrapY) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
y += h;
|
|
61
|
-
my += h;
|
|
62
|
-
}
|
|
63
|
-
while (y > maxY) {
|
|
64
|
-
y -= h;
|
|
65
|
-
my -= h;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
52
|
+
if (this.wrapY && maxY > minY) {
|
|
53
|
+
const wrapped = wrapToroidalAxis(y, my, minY, maxY, extents.top, extents.bottom, particle.velocity.y);
|
|
54
|
+
y = wrapped.position;
|
|
55
|
+
my = wrapped.movement;
|
|
68
56
|
}
|
|
69
57
|
particle.x = x;
|
|
70
58
|
particle.y = y;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToroidalWrapBehaviour.js","sourceRoot":"","sources":["../../../src/lib/behaviour/ToroidalWrapBehaviour.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,aAAa,CAAA;AACnC,OAAO,cAAc,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"ToroidalWrapBehaviour.js","sourceRoot":"","sources":["../../../src/lib/behaviour/ToroidalWrapBehaviour.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type Particle from '../Particle';
|
|
2
|
+
export type ToroidalEdgeExtents = {
|
|
3
|
+
left: number;
|
|
4
|
+
right: number;
|
|
5
|
+
top: number;
|
|
6
|
+
bottom: number;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Axis-aligned edge offsets from particle center to sprite bounds.
|
|
10
|
+
* Falls back to scaled size when no sprite/texture is available yet.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getToroidalEdgeExtents(particle: Particle): ToroidalEdgeExtents;
|
|
13
|
+
export type ToroidalAxisWrapResult = {
|
|
14
|
+
position: number;
|
|
15
|
+
movement: number;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Wraps one axis only after the particle is fully outside the bounds,
|
|
19
|
+
* placing it fully outside on the opposite side to avoid visible jumps.
|
|
20
|
+
* Velocity sign prevents re-wrapping when the particle is entering from off-screen.
|
|
21
|
+
*/
|
|
22
|
+
export declare function wrapToroidalAxis(position: number, movement: number, min: number, max: number, leadingExtent: number, trailingExtent: number, axisVelocity: number): ToroidalAxisWrapResult;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Axis-aligned edge offsets from particle center to sprite bounds.
|
|
3
|
+
* Falls back to scaled size when no sprite/texture is available yet.
|
|
4
|
+
*/
|
|
5
|
+
export function getToroidalEdgeExtents(particle) {
|
|
6
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7
|
+
const sprite = particle.sprite;
|
|
8
|
+
const texture = sprite === null || sprite === void 0 ? void 0 : sprite.texture;
|
|
9
|
+
if (sprite && texture) {
|
|
10
|
+
const scaleX = Math.abs(sprite.scale.x);
|
|
11
|
+
const scaleY = Math.abs(sprite.scale.y);
|
|
12
|
+
const width = texture.width * scaleX;
|
|
13
|
+
const height = texture.height * scaleY;
|
|
14
|
+
const anchorX = (_b = (_a = sprite.anchor) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 0.5;
|
|
15
|
+
const anchorY = (_d = (_c = sprite.anchor) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 0.5;
|
|
16
|
+
const rotation = (_f = (_e = sprite.rotation) !== null && _e !== void 0 ? _e : particle.rotation) !== null && _f !== void 0 ? _f : 0;
|
|
17
|
+
const cos = Math.abs(Math.cos(rotation));
|
|
18
|
+
const sin = Math.abs(Math.sin(rotation));
|
|
19
|
+
const halfW = (width * cos + height * sin) / 2;
|
|
20
|
+
const halfH = (width * sin + height * cos) / 2;
|
|
21
|
+
const centerOffsetX = width * (0.5 - anchorX) * cos - height * (0.5 - anchorY) * sin;
|
|
22
|
+
const centerOffsetY = width * (0.5 - anchorX) * sin + height * (0.5 - anchorY) * cos;
|
|
23
|
+
return {
|
|
24
|
+
left: halfW - centerOffsetX,
|
|
25
|
+
right: halfW + centerOffsetX,
|
|
26
|
+
top: halfH - centerOffsetY,
|
|
27
|
+
bottom: halfH + centerOffsetY,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const fallback = Math.max(Math.abs(particle.size.x), Math.abs(particle.size.y)) * 0.5;
|
|
31
|
+
return { left: fallback, right: fallback, top: fallback, bottom: fallback };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Wraps one axis only after the particle is fully outside the bounds,
|
|
35
|
+
* placing it fully outside on the opposite side to avoid visible jumps.
|
|
36
|
+
* Velocity sign prevents re-wrapping when the particle is entering from off-screen.
|
|
37
|
+
*/
|
|
38
|
+
export function wrapToroidalAxis(position, movement, min, max, leadingExtent, trailingExtent, axisVelocity) {
|
|
39
|
+
let pos = position;
|
|
40
|
+
let mov = movement;
|
|
41
|
+
while (pos + trailingExtent < min && axisVelocity < 0) {
|
|
42
|
+
const overflow = min - pos - trailingExtent;
|
|
43
|
+
const next = max + leadingExtent + overflow;
|
|
44
|
+
mov += next - pos;
|
|
45
|
+
pos = next;
|
|
46
|
+
}
|
|
47
|
+
while (pos - leadingExtent > max && axisVelocity > 0) {
|
|
48
|
+
const overflow = pos - leadingExtent - max;
|
|
49
|
+
const next = min - trailingExtent - overflow;
|
|
50
|
+
mov += next - pos;
|
|
51
|
+
pos = next;
|
|
52
|
+
}
|
|
53
|
+
return { position: pos, movement: mov };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=toroidalWrapExtents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toroidalWrapExtents.js","sourceRoot":"","sources":["../../../src/lib/util/toroidalWrapExtents.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED