fuzzyworld

bubbles / files / src / rendering / GlassRenderer.ts

GlassRenderer.ts

2.1 KB · history · blame

1/**
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
34 /** Draw the sealed glass container outline over everything. */
35 draw(): void {
36 const ctx = this.ctx;
37 const { x, y, w, h, wallThick: wt } = this;
38
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
45 // Walls and top/bottom (sealed rectangle)
46 ctx.fillStyle = 'rgba(186, 230, 253, 0.55)';
47 // Left wall (full height including top+bottom overlap)
48 ctx.fillRect(x - wt, y - wt, wt, h + wt * 2);
49 // Right wall
50 ctx.fillRect(x + w, y - wt, wt, h + wt * 2);
51 // Top (sealed)
52 ctx.fillRect(x - wt, y - wt, w + wt * 2, wt);
53 // Bottom
54 ctx.fillRect(x - wt, y + h, w + wt * 2, wt);
55
56 // Inner highlight — left edge
57 ctx.fillStyle = 'rgba(255, 255, 255, 0.18)';
58 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);
63
64 ctx.restore();
65 }
66}