Paint the stands once

- The opaque menu no longer has the whole court rendered behind it at full
  resolution — minutes of battery burn nobody could see.
- Stands, ads, rot tint, court, lines and the run-off are one cached blit,
  rebuilt only when the palette actually moves; the clap ripple stays live.
- RES derives from devicePixelRatio (capped at 4), so a 2x phone stops
  painting double the pixels it can show.
- One shared noise buffer for every synthesized sound — applause alone was
  allocating ~200 fresh buffers per cheer.
- The touch-steer path stops re-measuring a fixed canvas rect per move event.

Skipped as not-quick: the z-sort closure churn and swap-remove splices —
real but small, and each is a behavior-preserving refactor for another day.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-08-06 09:36:17 +02:00
1 parent f1f0d05a61
commit e07196f247
4 files changed
+173 -129

No files matched your search

+4 -2
View File
@@ -77,7 +77,9 @@ cv.addEventListener('touchstart', e => {
if (slot >= 0) { selectWeapon(slot); continue; }
}
if (!stick) {
stick = { id: t.identifier, x0: t.clientX, y0: t.clientY, t0: performance.now(),
// `r` rides along: the canvas is position: fixed, so its rect only moves on viewport changes
// — re-measuring it per touchmove (60-120 Hz on iOS) was layout work for a constant answer
stick = { id: t.identifier, x0: t.clientX, y0: t.clientY, t0: performance.now(), r,
moved: false, aimable: canAimServe() }; // context locked at touch start — a movement drag never morphs into a serve
// the reticle appears the moment the thumb lands, but mag 0 aims at nothing — you have to pull
if (stick.aimable) G.aim = { fx: 0, fy: 0, mag: 0 };
@@ -118,7 +120,7 @@ cv.addEventListener('touchmove', e => {
} else G.aim = { fx: 0, fy: 0, mag: 0 };
continue;
}
const r = cv.getBoundingClientRect();
const r = stick.r;
steerPX = (t.clientX - r.left) / r.width * 2 - 1;
touchAxis.x = Math.abs(dx) > DEAD ? Math.sign(dx) : 0;
touchAxis.z = Math.abs(dy) > DEAD ? Math.sign(dy) : 0;