fuzzyworld

bubbles / files / src / rendering / IconRenderer.ts

IconRenderer.ts

1.3 KB · history · blame

1import { RigidBody } from '../physics/RigidBody.js';
2import { Water } from '../physics/Water.js';
3
4const FONT_SCALE = 1.55; // emoji size relative to body radius
5
6export class IconRenderer {
7 constructor(
8 private readonly ctx: CanvasRenderingContext2D,
9 private readonly water: Water,
10 public glassX: number,
11 public glassY: number,
12 ) { }
13
14 draw(bodies: RigidBody[], getRefractionDx: (x: number) => number): void {
15 const ctx = this.ctx;
16
17 for (const body of bodies) {
18 const r = body.radius;
19 const size = r * FONT_SCALE * 2;
20 const bx = body.position.x;
21 const by = body.position.y;
22
23 // Determine if center is below water surface (for refraction offset)
24 const localX = bx - this.glassX;
25 const surfaceY = this.glassY + this.water.getSurfaceY(Math.max(0, localX));
26 const submerged = by > surfaceY;
27
28 ctx.save();
29 ctx.translate(bx + (submerged ? getRefractionDx(bx) : 0), by);
30 ctx.rotate(body.angle);
31
32 // Draw emoji
33 ctx.font = `${size}px serif`;
34 ctx.textAlign = 'center';
35 ctx.textBaseline = 'middle';
36 ctx.fillText(body.label, 0, 0);
37
38 ctx.restore();
39 }
40 }
41}