(time: number)
| 497 | * Update loop |
| 498 | */ |
| 499 | const update = (time: number) => { |
| 500 | const deltaTime = lastTimeRef.current ? (time - lastTimeRef.current) / 1000 : 0.016; |
| 501 | lastTimeRef.current = time; |
| 502 | |
| 503 | const dt = isPlaying ? deltaTime * data.playbackSpeed : 0; |
| 504 | noiseTimeRef.current += dt * noiseScrollSpeed; |
| 505 | |
| 506 | // 手动触发爆发(点击触发)| Manual burst trigger (click to emit) |
| 507 | if (triggerBurst !== lastTriggerBurstRef.current) { |
| 508 | lastTriggerBurstRef.current = triggerBurst; |
| 509 | // 触发所有 burst 配置 | Trigger all burst configs |
| 510 | if (bursts.length > 0) { |
| 511 | for (const burst of bursts) { |
| 512 | for (let j = 0; j < burst.count && particlesRef.current.length < data.maxParticles; j++) { |
| 513 | emitParticle(); |
| 514 | } |
| 515 | } |
| 516 | } else { |
| 517 | // 如果没有 burst 配置,发射一些默认粒子 | If no burst config, emit some default particles |
| 518 | const defaultCount = Math.min(data.maxParticles, 50); |
| 519 | for (let j = 0; j < defaultCount && particlesRef.current.length < data.maxParticles; j++) { |
| 520 | emitParticle(); |
| 521 | } |
| 522 | } |
| 523 | } |
| 524 | |
| 525 | if (isPlaying) { |
| 526 | elapsedTimeRef.current += dt; |
| 527 | |
| 528 | // 持续发射 | Continuous emission |
| 529 | emissionAccumulatorRef.current += data.emissionRate * dt; |
| 530 | while (emissionAccumulatorRef.current >= 1 && particlesRef.current.length < data.maxParticles) { |
| 531 | emitParticle(); |
| 532 | emissionAccumulatorRef.current -= 1; |
| 533 | } |
| 534 | |
| 535 | // 爆发发射 | Burst emission |
| 536 | for (let i = 0; i < bursts.length; i++) { |
| 537 | const burst = bursts[i]; |
| 538 | if (!burstFiredRef.current.has(i) && elapsedTimeRef.current >= burst.time) { |
| 539 | for (let j = 0; j < burst.count && particlesRef.current.length < data.maxParticles; j++) { |
| 540 | emitParticle(); |
| 541 | } |
| 542 | burstFiredRef.current.add(i); |
| 543 | } |
| 544 | } |
| 545 | |
| 546 | // 更新粒子 | Update particles |
| 547 | particlesRef.current = particlesRef.current.filter(p => { |
| 548 | p.age += dt; |
| 549 | if (p.age >= p.lifetime) return false; |
| 550 | |
| 551 | const normalizedAge = p.age / p.lifetime; |
| 552 | |
| 553 | // VelocityOverLifetime 模块 | Velocity module |
| 554 | if (velocityEnabled) { |
| 555 | // 阻力 | Drag |
| 556 | if (linearDrag > 0) { |
nothing calls this directly
no test coverage detected