bridge-droid-beam.ts

Droid railgun beam rendering. Four-layer composite beam VFX plus muzzle flash, drawn in screen space via the active camera transform.

What it does

Renders a single droid railgun beam from one world point to another for one frame. Stacks four straight strokes (haze, glow, core, thread) along the same segment, then paints a small muzzle-flash disc at the origin. All alphas scale linearly with a caller-supplied fadeFrac.

Exports

SymbolKindSignature
drawDroidBeamfunction(ctx, wx1, wy1, wx2, wy2, fadeFrac) => void

drawDroidBeam — parameters

ParamTypeMeaning
ctxCanvasRenderingContext2DTarget 2D context. Save/restore wrapped.
wx1, wy1numberWorld-space origin (muzzle end).
wx2, wy2numberWorld-space terminus (target end).
fadeFracnumber0..1 fade multiplier; multiplied into every layer alpha and the muzzle alpha.

Render pipeline

  1. Convert both world endpoints to screen coords via Camera.toS.
  2. ctx.save(), lineCap = 'round'.
  3. Four straight strokes from s1 to s2, painter’s order (back to front):
LayerRolestrokeStylelineWidth (px)globalAlpha
1Outer haze#aa22cc16 * camera.zoom0.12 * fadeFrac
2Mid glow#ff44ff8 * camera.zoom0.25 * fadeFrac
3Bright core#ff88ff3 * camera.zoom0.70 * fadeFrac
4White thread#ffffff1 * camera.zoom1.00 * fadeFrac
  1. Muzzle flash: filled circle at s1, radius 4 * camera.zoom, fillStyle = '#ff88ff', globalAlpha = 0.6 * fadeFrac.
  2. ctx.restore().

Coordinate space

Endpoints arrive in world coords; conversion to screen space goes through Camera.toS(wx, wy) (from ./rendering/camera). Line widths and the muzzle radius scale by camera.zoom (from ./core/state) so the beam keeps its apparent thickness at any zoom level.

Color identity

Magenta/violet stack: outer haze is a deep violet #aa22cc, mid/core graduate through #ff44ff and #ff88ff, capped by a pure white thread. Muzzle flash matches the core hue #ff88ff.

Side effects

  • Mutates ctx state (globalAlpha, strokeStyle, lineWidth, fillStyle, lineCap) but restores via save/restore.
  • No allocations beyond the implicit screen-space points returned by Camera.toS.
  • One-shot draw: no internal timing, no per-frame state. Caller owns lifetime and fade.

Imports

FromUsed as
./rendering/cameraCamera.toS for world→screen conversion
./core/statecamera.zoom scalar for stroke/disc sizing

Caller contract

  • Caller decides when the beam exists and supplies fadeFrac per frame (typically a decaying envelope).
  • Endpoints are world coords; do not pre-transform.
  • Safe to call from any 2D-canvas render pass; no z-ordering enforced beyond the four-layer painter’s order inside the function.

EXTRACT-CANDIDATE

  • The four-stroke composite-beam pattern (haze/glow/core/thread, alpha + width per layer, all from s1 to s2) is generic. Could be lifted into a shared drawCompositeBeam(ctx, s1, s2, layers, fadeFrac) helper if another weapon adopts the same look.
  • Magenta palette (#aa22cc, #ff44ff, #ff88ff) is hard-coded; if more droid VFX share it, hoist to a named palette constant.
  • Line widths 16/8/3/1 and alphas 0.12/0.25/0.7/1.0 are magic numbers in the body — candidates for a DROID_BEAM_LAYERS data table per the “every number traces to a named constant” rule.
  • Muzzle-flash radius 4 and alpha 0.6 likewise.