Worker orbs: pseudo-3D orbital depth — orbs pass behind the nucleus
Each worker orb gets a slow z-oscillation (-1 back .. +1 front); orbs draw in painter's order with the hub pinned at z=0, so the cluster visibly swings behind and in front of the nucleus instead of drifting on a flat plane. Depth scales size ±18% and dims the back arc; the physics stay 2D. Effect eases out during the hover-expand morph so orbs land on their buttons at natural size.
This commit is contained in:
parent
ee13bc8a05
commit
6e4c56c5d9
1 changed files with 28 additions and 7 deletions
|
|
@ -103,6 +103,12 @@
|
|||
homeX: 0, homeY: 0,
|
||||
visible: true,
|
||||
phase: Math.random() * Math.PI * 2,
|
||||
// Pseudo-3D orbital depth: z oscillates -1 (behind the nucleus,
|
||||
// smaller + dimmer) to +1 (in front, larger + brighter). Pure
|
||||
// draw-time effect — the force physics stay 2D.
|
||||
z: 0,
|
||||
zPhase: Math.random() * Math.PI * 2,
|
||||
zSpeed: 0.22 + Math.random() * 0.18,
|
||||
active: false,
|
||||
statusSeen: false, // has a real WS status arrived for this worker?
|
||||
lastProcessed: 0, // cumulative matched+not_found seen last update
|
||||
|
|
@ -662,8 +668,23 @@
|
|||
// ── Drawing ──
|
||||
|
||||
function drawOrbs(ctx, visible, time) {
|
||||
// ── Depth pass ──
|
||||
// Each worker orb drifts on a slow z-oscillation; the hub sits at z=0.
|
||||
// Painter's order (back → front) makes orbs visibly pass BEHIND the
|
||||
// nucleus and swing back in front — the flat drift reads as an atom.
|
||||
// The effect eases out during the hover-expand morph so orbs land on
|
||||
// their buttons at natural size.
|
||||
const depthFade = state === 'expanding' ? (1 - expandProgress) : 1;
|
||||
for (const orb of visible) {
|
||||
orb.z = orb.hub ? 0 : Math.sin(time * orb.zSpeed + orb.zPhase) * depthFade;
|
||||
}
|
||||
const ordered = [...visible].sort((a, b) => a.z - b.z);
|
||||
|
||||
for (const orb of ordered) {
|
||||
const [r, g, b] = orb.rainbow ? getRainbowColor(time) : orb.color;
|
||||
// -1 (back): ~18% smaller, dimmer. +1 (front): ~18% larger, full.
|
||||
const dScale = 1 + orb.z * 0.18;
|
||||
const dAlpha = 0.78 + 0.22 * ((orb.z + 1) / 2);
|
||||
|
||||
// ── The hub: an energy-reactive nucleus ──
|
||||
// Calm + dim when nothing's running; bigger, brighter and faster
|
||||
|
|
@ -749,25 +770,25 @@
|
|||
baseRadius += 2 * Math.sin(time * 3 + orb.phase);
|
||||
}
|
||||
|
||||
// Scale up during expand transition
|
||||
const currentRadius = state === 'expanding'
|
||||
// Scale up during expand transition; depth scales the whole orb
|
||||
const currentRadius = (state === 'expanding'
|
||||
? baseRadius + expandProgress * 4
|
||||
: baseRadius;
|
||||
: baseRadius) * dScale;
|
||||
|
||||
// Inactive orbs are dimmer
|
||||
const activeMult = orb.active ? 1.0 : 0.45;
|
||||
|
||||
// Outer glow — much larger and brighter for active
|
||||
const glowRadius = orb.active ? currentRadius * 5 : currentRadius * 3;
|
||||
const glowAlpha = orb.active
|
||||
const glowAlpha = (orb.active
|
||||
? (0.25 + pulse * 0.2) * activeMult
|
||||
: (0.06 + pulse * 0.03) * activeMult;
|
||||
: (0.06 + pulse * 0.03) * activeMult) * dAlpha;
|
||||
drawGlow(ctx, orb.x, orb.y, glowRadius, r, g, b, glowAlpha);
|
||||
|
||||
// Core
|
||||
const coreAlpha = orb.active
|
||||
const coreAlpha = (orb.active
|
||||
? 0.85 + pulse * 0.15
|
||||
: (0.3 + pulse * 0.08) * activeMult;
|
||||
: (0.3 + pulse * 0.08) * activeMult) * dAlpha;
|
||||
ctx.beginPath();
|
||||
ctx.arc(orb.x, orb.y, Math.max(1, currentRadius), 0, Math.PI * 2);
|
||||
ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${coreAlpha})`;
|
||||
|
|
|
|||
Loading…
Reference in a new issue