PURPOSE

Renders a single ShootingStar entity to the 2D canvas: a rainbow-hued tail, a pulsing 5-pointed golden star, an intense radial outer glow, and a spinning golden collection ring with cardinal/diagonal tick marks. Includes a separate “collected” mode that flies the star toward screen center with growing scale and brighter glow.

OWNS

  • SCALE constant — visual scale multiplier (1.0, 1:1 with archive original).
  • RAINBOW_HUES palette — seven RGB triplets cycled along the tail (red, orange, yellow, green, blue, indigo, violet).
  • FLY_DURATION constant — 0.6s, mirrors STAR_FLY_DURATION in shooting-star.ts.
  • _safeRadialGradient helper — wraps ctx.createRadialGradient clamping inner radius to ≥0.01 and outer radius to ≥0.1.
  • _starPath helper — traces a 10-vertex (5-pointed) star polygon into the current 2D path centered at (0,0), alternating outer/inner radii.
  • drawShootingStar exported function — the renderer entry point.
  • The full visual composition: tail strokes, white-hot core trail, outer glow gradient, three-layer star fill (white / #ffcc33 / #ff8800), outer/inner golden rings, eight tick marks.

READS FROM

  • ShootingStar type from ../world/shooting-star.
  • Camera.toS(x, y) from ./camera — converts world coordinates to screen coordinates for the star center and every trail sample.
  • W, H from ../core/state — screen dimensions used to compute the flight target (W/2, H/2) in collected mode.
  • Star fields read: _collected, _collectTime, _collectScreenX, _collectScreenY, x, y, trail (array of {x, y} samples), spin.
  • Caller-supplied: ctx (2D context), zoom, time (world clock for pulse/ring oscillation), idx (per-star phase offset), uiTime (optional, drives collected-mode interpolation).

PUSHES TO

  • The supplied CanvasRenderingContext2D — mutates globalAlpha, fillStyle, strokeStyle, lineWidth, lineCap, and the transform stack via save/translate/rotate/scale/restore.
  • Resets ctx.globalAlpha = 1 before returning from both the collected branch and the live branch.

DOES NOT

  • Does not mutate the ShootingStar itself (no writes to position, spin, trail, or collection flags).
  • Does not iterate the global star list — caller drives the per-star loop and supplies idx.
  • Does not handle input, collision, scoring, or trail growth.
  • Does not load assets, fonts, or sprite atlases — purely procedural canvas drawing.
  • Does not check whether the star is on-screen; relies on caller-side culling if any.
  • Does not despawn or finalize the collection animation; just renders the current frame based on uiTime - _collectTime.

Signals

  • None emitted. Pure draw function with no event dispatch, no telemetry, no logging.

Entry points

  • drawShootingStar(ctx, star, zoom, time, idx, uiTime?) — the only exported symbol. Called per-frame per-star by the rendering pipeline.

Pattern notes

  • Two-branch structure: if star._collected && uiTime != null, runs the fly-to-center animation (ease-out quad on t = elapsed / FLY_DURATION, scale 1.0 → 1.5, amplified glow, simplified two-layer star) and early-returns; otherwise renders the full world-space presentation.
  • Trail rendering walks trail once for the rainbow strokes (hue index (ti * 0.8) % 7, alpha and width grow with frac = ti / tLen) and a second time for the last 12 samples as a white-hot polyline core.
  • Pulse animation: 1 + sin(time * 8 + idx * 2) * 0.15 scales the star body each frame; ring alphas oscillate at independent frequencies (sin(time * 4 + idx) and sin(time * 6 + idx * 3)).
  • Ring rotation is derived as (star.spin || 0) * 1.5, so it counter-spins relative to the star body.
  • All radii are multiplied by SCALE * zoom so the visual is consistent under camera zoom; SCALE is held at 1.0 but kept as a knob.
  • Underscored helpers (_safeRadialGradient, _starPath) are module-private by convention, not exported.
  • Comments reference the archive source (archive/html-source/08b-render-gameplay.js lines 2369-2516) the renderer is ported from, with the note that the port is 2× larger with enhanced glow.