PURPOSE
World-space renderer for a single artifact pickup, drawn as a green-blue swirling glass orb with a soft glow, an upward column of light, rotating swirl arcs, a specular highlight, and a pulsing outer ring. Called once per artifact box during the entity render pass.
OWNS
drawArtifactOrb(ctx, sz, time, phase, collecting)— the sole exported draw function.- The full visual treatment of an artifact pickup: glow radial gradient, vertical light beam (outer green + inner blue-white), base orb radial gradient (
#aaffee → #44ddbb → #2288aa → #114466), rotating swirl arcs, specular highlight dot, and pulsing teal outer ring stroke. - Local animation derivations from
timeandphase: glow pulse, beam pulse, swirl angle and arc length, ring alpha.
READS FROM
ctx: CanvasRenderingContext2D— already translated by the caller to the orb’s screen position.sz: number— base radius in screen pixels (camera zoom already applied by caller). Orb radius is derived assz * 1.1.time: number—game.time, drives all sinusoidal pulse and rotation terms.phase: number— per-pickup bob phase offset, used to desync animations between concurrent orbs.collecting: boolean— when true, the glow and column of light are skipped (used during the fly-to-center collect animation).
PUSHES TO
- The provided
CanvasRenderingContext2D. The function mutatesfillStyle,strokeStyle,lineWidth,globalAlpha, and issuesbeginPath/arc/fillRect/fill/strokecalls. - Restores
ctx.globalAlpha = 1before returning. Does not callctx.save/ctx.restore; relies on the caller for that.
DOES NOT
- Does not translate, rotate, or scale the context. The caller positions, bobs, and scales the orb.
- Does not read game state, world, camera, or any module-level data.
- Does not handle input, collision, collection logic, or the fly-to-center motion —
collectingis a render-only flag. - Does not draw the artifact icon, label, or rarity affordances; only the orb itself.
- Does not allocate persistent textures or use the sprite batch; gradients are recreated per call.
Signals
None. Pure rendering function with no event emission or subscription.
Entry points
drawArtifactOrbis imported bysrc/starship-survivors/engine/bridge.tsand called inside the artifact-box render loop, after the caller has saved the context, translated to screen position plus bob offset, and applied_collectScale.collectingis passed as!!aa._collecting,phaseasab.bobPhase || 0,timeasgame.time.
Pattern notes
- Procedural Canvas2D rendering — no sprites, atlases, or shaders. Every layer is a fresh gradient or arc per frame.
- Layer order is back-to-front: glow → beam (outer then inner) → base orb → swirl arcs → specular highlight → outer ring stroke.
- All animation is derived from
timeandphaseviaMath.sin, with distinct frequencies (2.5,2.1,1.8,1.2,3.0) so layers desync visually. - The
collectingshort-circuit skips the glow and beam so the orb reads cleanly during the collect tween; the base orb, swirls, highlight, and ring still draw. - Swirl arcs use a fixed count of three, alternating teal and blue-cyan strokes at increasing radii (
0.5 + i * 0.15oforbR). - Visual style is intentionally matched to the weapon chest beam (per file comment) so artifact and weapon pickups feel like a family.
- Caller-owned concerns: world-to-screen projection, bob offset, collect scale, and
ctx.save/ctx.restorebracketing.