custom-pixi-particles 8.18.1 → 8.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/lib/Model.d.ts +6 -0
  2. package/dist/lib/Model.js +8 -0
  3. package/dist/lib/Model.js.map +1 -1
  4. package/dist/lib/behaviour/TemperatureBehaviour.d.ts +49 -28
  5. package/dist/lib/behaviour/TemperatureBehaviour.js +303 -29
  6. package/dist/lib/behaviour/TemperatureBehaviour.js.map +1 -1
  7. package/dist/lib/behaviour/ToroidalWrapBehaviour.d.ts +8 -11
  8. package/dist/lib/behaviour/ToroidalWrapBehaviour.js +45 -41
  9. package/dist/lib/behaviour/ToroidalWrapBehaviour.js.map +1 -1
  10. package/dist/lib/emitter/Emitter.js +3 -0
  11. package/dist/lib/emitter/Emitter.js.map +1 -1
  12. package/dist/lib/parser/EmitterParser.js +3 -2
  13. package/dist/lib/parser/EmitterParser.js.map +1 -1
  14. package/dist/lib/pixi/Renderer.d.ts +3 -1
  15. package/dist/lib/pixi/Renderer.js +41 -19
  16. package/dist/lib/pixi/Renderer.js.map +1 -1
  17. package/dist/lib/pixi/SpriteContainerRenderer.d.ts +3 -1
  18. package/dist/lib/pixi/SpriteContainerRenderer.js +31 -15
  19. package/dist/lib/pixi/SpriteContainerRenderer.js.map +1 -1
  20. package/dist/lib/pixi/TestRenderer.d.ts +3 -1
  21. package/dist/lib/pixi/TestRenderer.js +39 -17
  22. package/dist/lib/pixi/TestRenderer.js.map +1 -1
  23. package/dist/lib/pixi/particleLinkLayer.d.ts +1 -1
  24. package/dist/lib/util/toroidalWrapExtents.d.ts +46 -0
  25. package/dist/lib/util/toroidalWrapExtents.js +110 -0
  26. package/dist/lib/util/toroidalWrapExtents.js.map +1 -0
  27. package/dist/lib/util/toroidalWrapVisibility.d.ts +5 -0
  28. package/dist/lib/util/toroidalWrapVisibility.js +12 -0
  29. package/dist/lib/util/toroidalWrapVisibility.js.map +1 -0
  30. package/package.json +2 -2
@@ -56,6 +56,12 @@ export default class Model {
56
56
  x: number;
57
57
  y: number;
58
58
  } | null;
59
+ /**
60
+ * Incremented when the host tab becomes visible again after being hidden.
61
+ * Behaviours use this to resync state after a pause (avoids delta spikes / stale wrap tracking).
62
+ */
63
+ visibilityResumeGeneration: number;
64
+ signalVisibilityResume(): void;
59
65
  /** Sets {@link toroidalCanvasBounds} from render buffer size (centered rect). */
60
66
  setToroidalCanvasBoundsFromSize(width: number, height: number): void;
61
67
  clearToroidalCanvasBounds(): void;
package/dist/lib/Model.js CHANGED
@@ -35,6 +35,14 @@ export default class Model {
35
35
  * Updated by Renderer.updatePosition when the host passes cursor/follow-mouse updates.
36
36
  */
37
37
  this.pointerWorld = null;
38
+ /**
39
+ * Incremented when the host tab becomes visible again after being hidden.
40
+ * Behaviours use this to resync state after a pause (avoids delta spikes / stale wrap tracking).
41
+ */
42
+ this.visibilityResumeGeneration = 0;
43
+ }
44
+ signalVisibilityResume() {
45
+ this.visibilityResumeGeneration += 1;
38
46
  }
39
47
  /** Sets {@link toroidalCanvasBounds} from render buffer size (centered rect). */
40
48
  setToroidalCanvasBoundsFromSize(width, height) {
@@ -1 +1 @@
1
- {"version":3,"file":"Model.js","sourceRoot":"","sources":["../../src/lib/Model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Model.js","sourceRoot":"","sources":["../../src/lib/Model.ts"],"names":[],"mappings":"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"}
@@ -1,47 +1,68 @@
1
1
  import Behaviour from './Behaviour';
2
2
  import Particle from '../Particle';
3
+ import type Model from '../Model';
3
4
  import { Color, Point } from '../util';
5
+ export type TemperatureZoneShapeType = 'circle' | 'square' | 'rectangle';
6
+ export type TemperatureZone = {
7
+ center: Point;
8
+ velocity: Point;
9
+ color: Color;
10
+ shapeType?: TemperatureZoneShapeType;
11
+ radius?: number;
12
+ halfSize?: number;
13
+ halfWidth?: number;
14
+ halfHeight?: number;
15
+ };
4
16
  /**
5
17
  * TemperatureBehaviour adjusts particle velocity and color
6
18
  * based on whether they are in a hot or cold zone.
19
+ *
20
+ * Runs after ColorBehaviour and ToroidalWrapBehaviour (lower priority):
21
+ * base color and final position are known before zone tinting is applied.
7
22
  */
8
23
  export default class TemperatureBehaviour extends Behaviour {
9
24
  enabled: boolean;
25
+ /** Below ToroidalWrapBehaviour (45) so zone checks use post-wrap positions. */
10
26
  priority: number;
11
- zones: {
12
- center: Point;
13
- radius: number;
14
- velocity: Point;
15
- color: Color;
16
- }[];
17
- /**
18
- * Initializes the particle. This behavior does not require
19
- * per-particle initialization, but it's included for extensibility.
20
- */
27
+ zones: TemperatureZone[];
28
+ /** When true, particle color eases toward zone / outside colors instead of snapping. */
29
+ gradualColorTransition: boolean;
30
+ /** Blend speed toward the target color (higher = faster). */
31
+ colorTransitionSpeed: number;
32
+ private _reconciledVisibilityResumeGeneration;
21
33
  init(particle: Particle): void;
34
+ apply(particle: Particle, deltaTime?: number, model?: Model): void;
35
+ onParticlesUpdated(model?: Model): void;
36
+ private applyGradualOutsideColor;
37
+ private getOutsideTarget;
38
+ private getRestoreOutsideColor;
22
39
  /**
23
- * Applies temperature-based adjustments to the particle's velocity and color.
24
- */
25
- apply(particle: Particle): void;
26
- /**
27
- * Checks if a particle is within a specified zone.
28
- */
29
- isInZone(particle: Particle, center: Point, radius: number): boolean;
30
- /**
31
- * Returns the name of the behavior.
40
+ * True when the particle is outside all zones but still carries zone tint
41
+ * (state desync, toroidal wrap, or mid-blend).
32
42
  */
43
+ private shouldInstantRestore;
44
+ private hasResidualZoneTint;
45
+ private syncColorSkip;
46
+ private clearGradualColorState;
47
+ private findActiveZone;
48
+ private zoneColor;
49
+ private copyColor;
50
+ private writeColor;
51
+ private mixColors;
52
+ private stepBlendToward;
53
+ private getBlendT;
54
+ private lerp;
55
+ private colorsNear;
56
+ private colorDistSq;
57
+ private matchesAnyZoneColor;
58
+ private matchesAnyZoneColorValue;
59
+ isInZone(particle: Particle, zone: TemperatureZone): boolean;
33
60
  getName(): string;
34
- /**
35
- * Returns properties for serialization or debugging.
36
- */
37
61
  getProps(): {
38
62
  enabled: boolean;
39
63
  priority: number;
40
- zones: {
41
- center: Point;
42
- radius: number;
43
- velocity: Point;
44
- color: Color;
45
- }[];
64
+ zones: TemperatureZone[];
65
+ gradualColorTransition: boolean;
66
+ colorTransitionSpeed: number;
46
67
  };
47
68
  }
@@ -3,61 +3,335 @@ 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
+ * Runs after ColorBehaviour and ToroidalWrapBehaviour (lower priority):
8
+ * base color and final position are known before zone tinting is applied.
6
9
  */
7
10
  export default class TemperatureBehaviour extends Behaviour {
8
11
  constructor() {
9
12
  super(...arguments);
10
13
  this.enabled = true;
11
- this.priority = 150;
14
+ /** Below ToroidalWrapBehaviour (45) so zone checks use post-wrap positions. */
15
+ this.priority = 40;
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;
21
+ this._reconciledVisibilityResumeGeneration = -1;
13
22
  }
14
- /**
15
- * Initializes the particle. This behavior does not require
16
- * per-particle initialization, but it's included for extensibility.
17
- */
18
23
  init(particle) {
19
- // Optionally, initialize particle-specific data here
24
+ const p = particle;
25
+ p._temperatureInZone = false;
26
+ p._temperatureTransitioningOut = false;
27
+ p._temperatureBlend = 0;
28
+ p._temperatureOutsideColor = null;
29
+ p._temperatureLastZoneColor = null;
30
+ p._toroidalJustWrapped = false;
31
+ particle.skipColorBehaviour = false;
20
32
  }
21
- /**
22
- * Applies temperature-based adjustments to the particle's velocity and color.
23
- */
24
- apply(particle) {
33
+ apply(particle, deltaTime = 1 / 60, model) {
34
+ var _a, _b, _c, _d;
25
35
  if (!this.enabled || !this.zones || !this.zones.length)
26
36
  return;
27
- // Check if the particle is in any hot zone
28
- for (const zone of this.zones) {
29
- if (this.isInZone(particle, zone.center, zone.radius)) {
30
- particle.velocity.x *= zone.velocity.x;
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;
37
+ const p = particle;
38
+ const justWrapped = p._toroidalJustWrapped === true;
39
+ if (justWrapped) {
40
+ p._toroidalJustWrapped = false;
41
+ }
42
+ const activeZone = this.findActiveZone(particle);
43
+ const naturalColor = this.copyColor(particle);
44
+ const wasInZone = p._temperatureInZone === true;
45
+ const visibilityResume = ((_a = model === null || model === void 0 ? void 0 : model.visibilityResumeGeneration) !== null && _a !== void 0 ? _a : 0) > this._reconciledVisibilityResumeGeneration;
46
+ let residualTint = !activeZone && this.hasResidualZoneTint(particle, p, wasInZone, justWrapped);
47
+ if (!activeZone &&
48
+ visibilityResume &&
49
+ (wasInZone || this.matchesAnyZoneColorValue(naturalColor, 12))) {
50
+ residualTint = true;
51
+ }
52
+ if (!activeZone) {
53
+ if (this.gradualColorTransition) {
54
+ if (residualTint) {
55
+ p._temperatureTransitioningOut = true;
56
+ }
57
+ this.applyGradualOutsideColor(particle, p, naturalColor, deltaTime);
58
+ }
59
+ else if (residualTint) {
60
+ const restoreColor = this.getRestoreOutsideColor(p, naturalColor);
61
+ if (restoreColor &&
62
+ (justWrapped && wasInZone || this.shouldInstantRestore(particle, naturalColor))) {
63
+ this.writeColor(particle, restoreColor);
64
+ }
65
+ }
66
+ else if (!wasInZone && !residualTint && !this.matchesAnyZoneColorValue(naturalColor)) {
67
+ p._temperatureOutsideColor = naturalColor;
36
68
  }
69
+ p._temperatureInZone = false;
70
+ this.syncColorSkip(particle, p, false);
71
+ if (!this.gradualColorTransition) {
72
+ this.clearGradualColorState(particle, p);
73
+ }
74
+ return;
75
+ }
76
+ if (this.gradualColorTransition) {
77
+ p._temperatureTransitioningOut = false;
78
+ if (!wasInZone) {
79
+ p._temperatureOutsideColor = naturalColor;
80
+ if (((_b = p._temperatureBlend) !== null && _b !== void 0 ? _b : 0) <= 0) {
81
+ p._temperatureBlend = 0;
82
+ }
83
+ }
84
+ else if (!p._temperatureOutsideColor) {
85
+ p._temperatureOutsideColor = naturalColor;
86
+ }
87
+ }
88
+ else if (!wasInZone) {
89
+ p._temperatureOutsideColor = naturalColor;
90
+ }
91
+ else if (justWrapped && !this.matchesAnyZoneColorValue(naturalColor, 12)) {
92
+ // Wrapped into a zone from a non-tinted color — refresh outside reference.
93
+ p._temperatureOutsideColor = naturalColor;
94
+ }
95
+ particle.velocity.x *= activeZone.velocity.x;
96
+ particle.velocity.y *= activeZone.velocity.y;
97
+ const zoneColor = this.zoneColor(activeZone);
98
+ p._temperatureLastZoneColor = zoneColor;
99
+ if (this.gradualColorTransition) {
100
+ const blend = this.stepBlendToward((_c = p._temperatureBlend) !== null && _c !== void 0 ? _c : 0, 1, deltaTime);
101
+ p._temperatureBlend = blend;
102
+ const outside = (_d = p._temperatureOutsideColor) !== null && _d !== void 0 ? _d : naturalColor;
103
+ this.writeColor(particle, this.mixColors(outside, zoneColor, blend));
37
104
  }
105
+ else {
106
+ this.writeColor(particle, zoneColor);
107
+ }
108
+ p._temperatureInZone = true;
109
+ this.syncColorSkip(particle, p, true);
110
+ }
111
+ onParticlesUpdated(model) {
112
+ var _a;
113
+ const resumeGeneration = (_a = model === null || model === void 0 ? void 0 : model.visibilityResumeGeneration) !== null && _a !== void 0 ? _a : 0;
114
+ if (resumeGeneration > this._reconciledVisibilityResumeGeneration) {
115
+ this._reconciledVisibilityResumeGeneration = resumeGeneration;
116
+ }
117
+ }
118
+ applyGradualOutsideColor(particle, p, naturalColor, deltaTime) {
119
+ var _a, _b, _c;
120
+ const transitioningOut = p._temperatureTransitioningOut === true;
121
+ const startBlend = transitioningOut ? ((_a = p._temperatureBlend) !== null && _a !== void 0 ? _a : 1) : ((_b = p._temperatureBlend) !== null && _b !== void 0 ? _b : 0);
122
+ if (!transitioningOut &&
123
+ !this.matchesAnyZoneColorValue(naturalColor) &&
124
+ !this.hasResidualZoneTint(particle, p, false, false)) {
125
+ p._temperatureOutsideColor = naturalColor;
126
+ }
127
+ const blend = this.stepBlendToward(startBlend, 0, deltaTime);
128
+ p._temperatureBlend = blend;
129
+ if (!transitioningOut && blend <= 0.001) {
130
+ p._temperatureBlend = 0;
131
+ p._temperatureTransitioningOut = false;
132
+ p._temperatureLastZoneColor = null;
133
+ this.syncColorSkip(particle, p, false);
134
+ return;
135
+ }
136
+ const outside = this.getOutsideTarget(p, naturalColor);
137
+ const zone = (_c = p._temperatureLastZoneColor) !== null && _c !== void 0 ? _c : outside;
138
+ this.writeColor(particle, this.mixColors(outside, zone, blend));
139
+ if (blend <= 0.001) {
140
+ p._temperatureBlend = 0;
141
+ p._temperatureTransitioningOut = false;
142
+ p._temperatureLastZoneColor = null;
143
+ this.syncColorSkip(particle, p, false);
144
+ return;
145
+ }
146
+ this.syncColorSkip(particle, p, false);
147
+ }
148
+ getOutsideTarget(p, naturalColor) {
149
+ var _a, _b;
150
+ if (p._temperatureTransitioningOut === true) {
151
+ return (_a = this.getRestoreOutsideColor(p, naturalColor)) !== null && _a !== void 0 ? _a : naturalColor;
152
+ }
153
+ return (_b = p._temperatureOutsideColor) !== null && _b !== void 0 ? _b : naturalColor;
154
+ }
155
+ getRestoreOutsideColor(p, naturalColor) {
156
+ const outside = p._temperatureOutsideColor;
157
+ if (!outside)
158
+ return null;
159
+ if (!this.matchesAnyZoneColorValue(outside, 12))
160
+ return outside;
161
+ // Outside reference was corrupted (e.g. saved while zone-tinted after a wrap).
162
+ if (!this.matchesAnyZoneColorValue(naturalColor, 12))
163
+ return naturalColor;
164
+ return null;
38
165
  }
39
166
  /**
40
- * Checks if a particle is within a specified zone.
167
+ * True when the particle is outside all zones but still carries zone tint
168
+ * (state desync, toroidal wrap, or mid-blend).
41
169
  */
42
- isInZone(particle, center, radius) {
43
- const dx = particle.movement.x - center.x;
44
- const dy = particle.movement.y - center.y;
170
+ shouldInstantRestore(particle, naturalColor) {
171
+ if (this.matchesAnyZoneColorValue(naturalColor, 12))
172
+ return true;
173
+ const p = particle;
174
+ const outside = p._temperatureOutsideColor;
175
+ const zone = p._temperatureLastZoneColor;
176
+ if (!outside || !zone)
177
+ return false;
178
+ if (this.colorsNear(naturalColor, outside))
179
+ return false;
180
+ if (this.colorsNear(naturalColor, zone, 12))
181
+ return true;
182
+ const distToZone = this.colorDistSq(naturalColor, zone);
183
+ const distToOutside = this.colorDistSq(naturalColor, outside);
184
+ return distToZone < distToOutside * 0.35 && distToZone <= 3600;
185
+ }
186
+ hasResidualZoneTint(particle, p, wasInZone, justWrapped) {
187
+ var _a;
188
+ if (justWrapped)
189
+ return true;
190
+ if (p._temperatureTransitioningOut === true)
191
+ return true;
192
+ if (this.gradualColorTransition && ((_a = p._temperatureBlend) !== null && _a !== void 0 ? _a : 0) > 0.001)
193
+ return true;
194
+ if (this.matchesAnyZoneColorValue(this.copyColor(particle), 12))
195
+ return true;
196
+ const outside = p._temperatureOutsideColor;
197
+ const zone = p._temperatureLastZoneColor;
198
+ if (!outside || !zone) {
199
+ return wasInZone && this.matchesAnyZoneColorValue(this.copyColor(particle), 12);
200
+ }
201
+ const current = this.copyColor(particle);
202
+ if (this.colorsNear(current, outside))
203
+ return false;
204
+ if (this.colorsNear(current, zone, 12))
205
+ return true;
206
+ const distToZone = this.colorDistSq(current, zone);
207
+ const distToOutside = this.colorDistSq(current, outside);
208
+ return distToZone < distToOutside * 0.35 && distToZone <= 3600;
209
+ }
210
+ syncColorSkip(particle, p, inZone) {
211
+ var _a;
212
+ if (!this.gradualColorTransition) {
213
+ particle.skipColorBehaviour = inZone;
214
+ return;
215
+ }
216
+ const blend = (_a = p._temperatureBlend) !== null && _a !== void 0 ? _a : 0;
217
+ particle.skipColorBehaviour =
218
+ inZone || p._temperatureTransitioningOut === true || blend > 0.001;
219
+ }
220
+ clearGradualColorState(particle, p) {
221
+ p._temperatureBlend = 0;
222
+ if (!this.hasResidualZoneTint(particle, p, false, false)) {
223
+ p._temperatureLastZoneColor = null;
224
+ }
225
+ }
226
+ findActiveZone(particle) {
227
+ for (const zone of this.zones) {
228
+ if (this.isInZone(particle, zone)) {
229
+ return zone;
230
+ }
231
+ }
232
+ return null;
233
+ }
234
+ zoneColor(zone) {
235
+ var _a;
236
+ return {
237
+ r: zone.color.r,
238
+ g: zone.color.g,
239
+ b: zone.color.b,
240
+ alpha: (_a = zone.color.alpha) !== null && _a !== void 0 ? _a : 1,
241
+ };
242
+ }
243
+ copyColor(particle) {
244
+ return {
245
+ r: particle.color.r,
246
+ g: particle.color.g,
247
+ b: particle.color.b,
248
+ alpha: particle.color.alpha,
249
+ };
250
+ }
251
+ writeColor(particle, color) {
252
+ particle.color.r = color.r;
253
+ particle.color.g = color.g;
254
+ particle.color.b = color.b;
255
+ particle.color.alpha = color.alpha;
256
+ }
257
+ mixColors(from, to, blend) {
258
+ const t = Math.max(0, Math.min(1, blend));
259
+ return {
260
+ r: this.lerp(from.r, to.r, t),
261
+ g: this.lerp(from.g, to.g, t),
262
+ b: this.lerp(from.b, to.b, t),
263
+ alpha: this.lerp(from.alpha, to.alpha, t),
264
+ };
265
+ }
266
+ stepBlendToward(current, target, deltaTime) {
267
+ const t = this.getBlendT(deltaTime);
268
+ const next = current + (target - current) * t;
269
+ if (target > current)
270
+ return Math.min(target, next);
271
+ return Math.max(target, next);
272
+ }
273
+ getBlendT(deltaTime) {
274
+ const speed = Math.max(0, this.colorTransitionSpeed);
275
+ if (speed <= 0)
276
+ return 0;
277
+ const dtSeconds = deltaTime >= 1 ? deltaTime / 60 : deltaTime;
278
+ return 1 - Math.exp(-speed * dtSeconds);
279
+ }
280
+ lerp(start, end, t) {
281
+ return start + (end - start) * t;
282
+ }
283
+ colorsNear(a, b, tolerance = 2) {
284
+ return (Math.abs(a.r - b.r) <= tolerance &&
285
+ Math.abs(a.g - b.g) <= tolerance &&
286
+ Math.abs(a.b - b.b) <= tolerance &&
287
+ Math.abs(a.alpha - b.alpha) <= 0.02);
288
+ }
289
+ colorDistSq(a, b) {
290
+ const dr = a.r - b.r;
291
+ const dg = a.g - b.g;
292
+ const db = a.b - b.b;
293
+ const da = (a.alpha - b.alpha) * 255;
294
+ return dr * dr + dg * dg + db * db + da * da;
295
+ }
296
+ matchesAnyZoneColor(particle, tolerance = 2) {
297
+ return this.matchesAnyZoneColorValue(this.copyColor(particle), tolerance);
298
+ }
299
+ matchesAnyZoneColorValue(color, tolerance = 2) {
300
+ for (const zone of this.zones) {
301
+ const zoneColor = this.zoneColor(zone);
302
+ if (this.colorsNear(color, zoneColor, tolerance)) {
303
+ return true;
304
+ }
305
+ }
306
+ return false;
307
+ }
308
+ isInZone(particle, zone) {
309
+ var _a, _b, _c, _d, _e;
310
+ const dx = particle.movement.x - zone.center.x;
311
+ const dy = particle.movement.y - zone.center.y;
312
+ const shapeType = (_a = zone.shapeType) !== null && _a !== void 0 ? _a : 'circle';
313
+ if (shapeType === 'square') {
314
+ const halfSize = (_b = zone.halfSize) !== null && _b !== void 0 ? _b : 0;
315
+ return Math.abs(dx) < halfSize && Math.abs(dy) < halfSize;
316
+ }
317
+ if (shapeType === 'rectangle') {
318
+ const halfWidth = (_c = zone.halfWidth) !== null && _c !== void 0 ? _c : 0;
319
+ const halfHeight = (_d = zone.halfHeight) !== null && _d !== void 0 ? _d : 0;
320
+ return Math.abs(dx) < halfWidth && Math.abs(dy) < halfHeight;
321
+ }
322
+ const radius = (_e = zone.radius) !== null && _e !== void 0 ? _e : 0;
45
323
  return Math.sqrt(dx * dx + dy * dy) < radius;
46
324
  }
47
- /**
48
- * Returns the name of the behavior.
49
- */
50
325
  getName() {
51
326
  return behaviourNames.TEMPERATURE_BEHAVIOUR;
52
327
  }
53
- /**
54
- * Returns properties for serialization or debugging.
55
- */
56
328
  getProps() {
57
329
  return {
58
330
  enabled: this.enabled,
59
331
  priority: this.priority,
60
332
  zones: this.zones,
333
+ gradualColorTransition: this.gradualColorTransition,
334
+ colorTransitionSpeed: this.colorTransitionSpeed,
61
335
  };
62
336
  }
63
337
  }
@@ -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;AAE7C;;;GAGG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,SAAS;IAA3D;;QACE,YAAO,GAAG,IAAI,CAAA;QACd,aAAQ,GAAG,GAAG,CAAA;QAEd,UAAK,GAAuE,EAAE,CAAA;IAuDhF,CAAC;IArDC;;;OAGG;IACH,IAAI,CAAC,QAAkB;QACrB,qDAAqD;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAkB;QACtB,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAM;QAE9D,2CAA2C;QAC3C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACtD,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;gBACtC,QAAQ,CAAC,QAAQ,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;gBACtC,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;gBAC/B,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;gBAC/B,QAAQ,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;gBAC/B,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,QAAQ,CAAC,QAAkB,EAAE,MAAa,EAAE,MAAc;QACxD,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAA;QACzC,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAA;QACzC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,MAAM,CAAA;IAC9C,CAAC;IAED;;OAEG;IACH,OAAO;QACL,OAAO,cAAc,CAAC,qBAAqB,CAAA;IAC7C,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAA;IACH,CAAC;CACF"}
1
+ {"version":3,"file":"TemperatureBehaviour.js","sourceRoot":"","sources":["../../../src/lib/behaviour/TemperatureBehaviour.ts"],"names":[],"mappings":"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"}
@@ -1,30 +1,27 @@
1
1
  import Behaviour from './Behaviour';
2
2
  import Particle from '../Particle';
3
3
  import type Model from '../Model';
4
- import type TurbulencePool from '../util/turbulencePool';
5
4
  /**
6
- * Toroidal screen/world wrap: particles that leave an axis-aligned rectangle
7
- * re-enter on the opposite side. Runs after {@link PositionBehaviour} (lower priority).
8
- * Syncs {@link Particle.movement} with wrapped {@link Particle.x}/{@link Particle.y}
9
- * (same pattern as {@link BounceBehaviour}). Do not combine with bounce on the same axis.
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
+ * Renderers hide sprites that do not overlap the viewport so teleports are never seen.
10
8
  */
11
9
  export default class ToroidalWrapBehaviour extends Behaviour {
12
10
  enabled: boolean;
13
11
  priority: number;
14
12
  wrapX: boolean;
15
13
  wrapY: boolean;
16
- /**
17
- * When true, bounds come from {@link Model.toroidalCanvasBounds} (set each frame from
18
- * `canvasSizeProvider` / renderer size). Manual min/max are ignored until turned off.
19
- */
20
14
  useCanvasBounds: boolean;
21
15
  minX: number;
22
16
  maxX: number;
23
17
  minY: number;
24
18
  maxY: number;
25
- /** Shrinks the effective wrap rect inward (helps large sprites). */
26
19
  inset: number;
27
- init: (_particle: Particle, _model: Model, _turbulencePool: TurbulencePool) => void;
20
+ private _insideX;
21
+ private _insideY;
22
+ private _handledVisibilityResumeGeneration;
23
+ init: (particle: Particle, _model: Model, _turbulencePool: unknown) => void;
24
+ onParticleRemoved: (particle: Particle) => void;
28
25
  apply: (particle: Particle, _deltaTime: number, model: Model) => void;
29
26
  getName(): string;
30
27
  getProps(): {