fuzzyworld

bubbles / files / src / rendering / GlassRenderer.ts

GlassRenderer.ts

Blame: the commit that last changed each line · file · history

dcc4757f 2026-04-09 Pavel Safronov1/**
2 * Draws the glass cup outline and establishes the clip region for the
3 * glass interior. Call beginClip() / endClip() around interior drawing.
4 *
5 * Glass geometry (all in canvas px):
6 * x, y — top-left of interior
7 * w, h — interior dimensions
8 * wallThick — wall / bottom thickness
9 * rimOverhang — extra px the rim extends above the interior top
10 */
11export class GlassRenderer {
12 constructor(
13 private readonly ctx: CanvasRenderingContext2D,
14 public x: number,
15 public y: number,
16 public w: number,
17 public h: number,
18 public wallThick: number = 8,
19 public rimOverhang: number = 4,
20 ) { }
21
22 /** Set a rectangular clip path matching the glass interior. */
23 beginClip(): void {
24 this.ctx.save();
25 this.ctx.beginPath();
26 this.ctx.rect(this.x, this.y, this.w, this.h);
27 this.ctx.clip();
28 }
29
30 endClip(): void {
31 this.ctx.restore();
32 }
33
775e32f9 2026-04-09 Pavel Safronov34 /** Draw the sealed glass container outline over everything. */
dcc4757f 2026-04-09 Pavel Safronov35 draw(): void {
36 const ctx = this.ctx;
775e32f9 2026-04-09 Pavel Safronov37 const { x, y, w, h, wallThick: wt } = this;
dcc4757f 2026-04-09 Pavel Safronov38
39 ctx.save();
40
41 // Glass tint fill (very subtle, mostly transparent)
42 ctx.fillStyle = 'rgba(186, 230, 253, 0.07)';
43 ctx.fillRect(x, y, w, h);
44
775e32f9 2026-04-09 Pavel Safronov45 // Walls and top/bottom (sealed rectangle)
dcc4757f 2026-04-09 Pavel Safronov46 ctx.fillStyle = 'rgba(186, 230, 253, 0.55)';
775e32f9 2026-04-09 Pavel Safronov47 // Left wall (full height including top+bottom overlap)
48 ctx.fillRect(x - wt, y - wt, wt, h + wt * 2);
dcc4757f 2026-04-09 Pavel Safronov49 // Right wall
775e32f9 2026-04-09 Pavel Safronov50 ctx.fillRect(x + w, y - wt, wt, h + wt * 2);
51 // Top (sealed)
52 ctx.fillRect(x - wt, y - wt, w + wt * 2, wt);
dcc4757f 2026-04-09 Pavel Safronov53 // Bottom
54 ctx.fillRect(x - wt, y + h, w + wt * 2, wt);
55
775e32f9 2026-04-09 Pavel Safronov56 // Inner highlight — left edge
dcc4757f 2026-04-09 Pavel Safronov57 ctx.fillStyle = 'rgba(255, 255, 255, 0.18)';
775e32f9 2026-04-09 Pavel Safronov58 ctx.fillRect(x - wt, y - wt, 3, h + wt * 2);
59 // Inner highlight — right edge
60 ctx.fillRect(x + w + wt - 3, y - wt, 3, h + wt * 2);
61 // Inner highlight — top edge
62 ctx.fillRect(x - wt, y - wt, w + wt * 2, 3);
dcc4757f 2026-04-09 Pavel Safronov63
64 ctx.restore();
65 }
66}