@vectojs/core 1.11.2 → 1.11.3

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/index.js CHANGED
@@ -179,6 +179,37 @@ var ComputeParticleEntity = (_class = class extends _chunk2Z23LTH3js.Entity {
179
179
  }
180
180
  render(_r) {
181
181
  }
182
+ /**
183
+ * True while any live particle still has a visually meaningful velocity or
184
+ * sits meaningfully away from its spring target.
185
+ *
186
+ * The actual per-frame simulation (WebGPU compute pass / {@link updateCPU})
187
+ * runs through a dedicated Scene-level pre-pass outside the normal
188
+ * render-tree walk, but this entity is still a normal tree member that
189
+ * walk visits — without this override, the base `Entity.hasPendingAnimations()`
190
+ * (always `false`) is what Scene sees, so `renderMode: 'always'`'s idle
191
+ * auto-throttle drops the WHOLE scene to ~2fps the instant nothing else in
192
+ * the tree is animating, even while thousands of particles are visibly
193
+ * drifting or spring-settling. A spring+damping system asymptotically
194
+ * approaches zero velocity but never reaches it exactly, so this checks
195
+ * against a small epsilon rather than `!== 0` — otherwise this would
196
+ * always return `true` and defeat the idle throttle entirely.
197
+ */
198
+ hasPendingAnimations() {
199
+ const EPS_VELOCITY = 0.5;
200
+ const EPS_DISTANCE = 0.5;
201
+ for (let i = 0; i < this.maxParticles; i++) {
202
+ const idx = i * PARTICLE_STRIDE_FLOATS;
203
+ if (this.particleData[idx + PARTICLE_OFFSET_LIFE] === 0) continue;
204
+ const vx = this.particleData[idx + PARTICLE_OFFSET_VELOCITY_X];
205
+ const vy = this.particleData[idx + PARTICLE_OFFSET_VELOCITY_Y];
206
+ if (vx * vx + vy * vy > EPS_VELOCITY * EPS_VELOCITY) return true;
207
+ const dx = this.particleData[idx + PARTICLE_OFFSET_POSITION_X] - this.particleData[idx + PARTICLE_OFFSET_ORIGIN_X];
208
+ const dy = this.particleData[idx + PARTICLE_OFFSET_POSITION_Y] - this.particleData[idx + PARTICLE_OFFSET_ORIGIN_Y];
209
+ if (dx * dx + dy * dy > EPS_DISTANCE * EPS_DISTANCE) return true;
210
+ }
211
+ return this.pendingExplosion !== null;
212
+ }
182
213
  /**
183
214
  * Updates particle simulation on the CPU.
184
215
  * Handles spring forces, mouse repulsion, explosion impulses, velocity capping, and bounds bouncing/clamping.
package/dist/index.mjs CHANGED
@@ -179,6 +179,37 @@ var ComputeParticleEntity = class extends Entity {
179
179
  }
180
180
  render(_r) {
181
181
  }
182
+ /**
183
+ * True while any live particle still has a visually meaningful velocity or
184
+ * sits meaningfully away from its spring target.
185
+ *
186
+ * The actual per-frame simulation (WebGPU compute pass / {@link updateCPU})
187
+ * runs through a dedicated Scene-level pre-pass outside the normal
188
+ * render-tree walk, but this entity is still a normal tree member that
189
+ * walk visits — without this override, the base `Entity.hasPendingAnimations()`
190
+ * (always `false`) is what Scene sees, so `renderMode: 'always'`'s idle
191
+ * auto-throttle drops the WHOLE scene to ~2fps the instant nothing else in
192
+ * the tree is animating, even while thousands of particles are visibly
193
+ * drifting or spring-settling. A spring+damping system asymptotically
194
+ * approaches zero velocity but never reaches it exactly, so this checks
195
+ * against a small epsilon rather than `!== 0` — otherwise this would
196
+ * always return `true` and defeat the idle throttle entirely.
197
+ */
198
+ hasPendingAnimations() {
199
+ const EPS_VELOCITY = 0.5;
200
+ const EPS_DISTANCE = 0.5;
201
+ for (let i = 0; i < this.maxParticles; i++) {
202
+ const idx = i * PARTICLE_STRIDE_FLOATS;
203
+ if (this.particleData[idx + PARTICLE_OFFSET_LIFE] === 0) continue;
204
+ const vx = this.particleData[idx + PARTICLE_OFFSET_VELOCITY_X];
205
+ const vy = this.particleData[idx + PARTICLE_OFFSET_VELOCITY_Y];
206
+ if (vx * vx + vy * vy > EPS_VELOCITY * EPS_VELOCITY) return true;
207
+ const dx = this.particleData[idx + PARTICLE_OFFSET_POSITION_X] - this.particleData[idx + PARTICLE_OFFSET_ORIGIN_X];
208
+ const dy = this.particleData[idx + PARTICLE_OFFSET_POSITION_Y] - this.particleData[idx + PARTICLE_OFFSET_ORIGIN_Y];
209
+ if (dx * dx + dy * dy > EPS_DISTANCE * EPS_DISTANCE) return true;
210
+ }
211
+ return this.pendingExplosion !== null;
212
+ }
182
213
  /**
183
214
  * Updates particle simulation on the CPU.
184
215
  * Handles spring forces, mouse repulsion, explosion impulses, velocity capping, and bounds bouncing/clamping.
@@ -99,6 +99,23 @@ export declare class ComputeParticleEntity extends Entity {
99
99
  triggerExplosion(x: number, y: number, force: number): void;
100
100
  isPointInside(_x: number, _y: number): boolean;
101
101
  render(_r: IRenderer): void;
102
+ /**
103
+ * True while any live particle still has a visually meaningful velocity or
104
+ * sits meaningfully away from its spring target.
105
+ *
106
+ * The actual per-frame simulation (WebGPU compute pass / {@link updateCPU})
107
+ * runs through a dedicated Scene-level pre-pass outside the normal
108
+ * render-tree walk, but this entity is still a normal tree member that
109
+ * walk visits — without this override, the base `Entity.hasPendingAnimations()`
110
+ * (always `false`) is what Scene sees, so `renderMode: 'always'`'s idle
111
+ * auto-throttle drops the WHOLE scene to ~2fps the instant nothing else in
112
+ * the tree is animating, even while thousands of particles are visibly
113
+ * drifting or spring-settling. A spring+damping system asymptotically
114
+ * approaches zero velocity but never reaches it exactly, so this checks
115
+ * against a small epsilon rather than `!== 0` — otherwise this would
116
+ * always return `true` and defeat the idle throttle entirely.
117
+ */
118
+ hasPendingAnimations(): boolean;
102
119
  /**
103
120
  * Updates particle simulation on the CPU.
104
121
  * Handles spring forces, mouse repulsion, explosion impulses, velocity capping, and bounds bouncing/clamping.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vectojs/core",
3
- "version": "1.11.2",
3
+ "version": "1.11.3",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },