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
| Symbol | Kind | Signature |
|---|---|---|
drawDroidBeam | function | (ctx, wx1, wy1, wx2, wy2, fadeFrac) => void |
drawDroidBeam — parameters
| Param | Type | Meaning |
|---|---|---|
ctx | CanvasRenderingContext2D | Target 2D context. Save/restore wrapped. |
wx1, wy1 | number | World-space origin (muzzle end). |
wx2, wy2 | number | World-space terminus (target end). |
fadeFrac | number | 0..1 fade multiplier; multiplied into every layer alpha and the muzzle alpha. |
Render pipeline
- Convert both world endpoints to screen coords via
Camera.toS. ctx.save(),lineCap = 'round'.- Four straight strokes from
s1tos2, painter’s order (back to front):
| Layer | Role | strokeStyle | lineWidth (px) | globalAlpha |
|---|---|---|---|---|
| 1 | Outer haze | #aa22cc | 16 * camera.zoom | 0.12 * fadeFrac |
| 2 | Mid glow | #ff44ff | 8 * camera.zoom | 0.25 * fadeFrac |
| 3 | Bright core | #ff88ff | 3 * camera.zoom | 0.70 * fadeFrac |
| 4 | White thread | #ffffff | 1 * camera.zoom | 1.00 * fadeFrac |
- Muzzle flash: filled circle at
s1, radius4 * camera.zoom,fillStyle = '#ff88ff',globalAlpha = 0.6 * fadeFrac. 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
ctxstate (globalAlpha,strokeStyle,lineWidth,fillStyle,lineCap) but restores viasave/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
| From | Used as |
|---|---|
./rendering/camera | Camera.toS for world→screen conversion |
./core/state | camera.zoom scalar for stroke/disc sizing |
Caller contract
- Caller decides when the beam exists and supplies
fadeFracper 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
s1tos2) is generic. Could be lifted into a shareddrawCompositeBeam(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/1and alphas0.12/0.25/0.7/1.0are magic numbers in the body — candidates for aDROID_BEAM_LAYERSdata table per the “every number traces to a named constant” rule. - Muzzle-flash radius
4and alpha0.6likewise.