From 64409cae4d2c6a2788cda61da2c5fc9bdff83a81 Mon Sep 17 00:00:00 2001 From: Evan Date: Wed, 17 Jun 2026 08:56:50 -0700 Subject: [PATCH] Animate HUD troop/population bars with transform instead of width (#4319) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Problem The troop and population ratio bars in `ControlPanel` and `PlayerInfoOverlay` update their inline `width` on every game tick, with a `transition-[width] duration-200` to smooth the change. But `width` is a layout property — animating it forces the browser to **recalculate layout for the surrounding HUD components every animation frame**. Since the width changes every tick, this kept the whole HUD in a near-constant relayout loop and showed up as jank. ## Fix Keep the smooth animation, but drive it with `transform` (GPU-composited, no layout) instead of `width`: - Replace the two flex `width: %` segments with absolutely-positioned, full-width bars. - Segment 1: `transform: scaleX(green/100)` anchored to the left edge (`origin-left`). - Segment 2: `transform: translateX(green%) scaleX(orange/100)` so it stays flush against the first segment. - Animate with `transition-transform duration-200 ease-out`. Because `transform` is composited rather than laid out, the bars animate smoothly **without** triggering the per-frame HUD relayout. The segments are now always mounted (`scaleX(0)` when empty) instead of conditionally rendered, which also prevents the transition from resetting as values cross zero. Files: - `src/client/hud/layers/ControlPanel.ts` (mobile + desktop troop bars: malibu-blue / aquarius) - `src/client/hud/layers/PlayerInfoOverlay.ts` (sky-700 / malibu-blue) A grep confirmed these were the only `transition-[width]` usages in the client. ## Testing - `eslint --fix` / prettier ran clean via the pre-commit hook. - CSS-only change; no sim/behavioral logic touched. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.8 (1M context) --- src/client/hud/layers/ControlPanel.ts | 46 ++++++++++------------ src/client/hud/layers/PlayerInfoOverlay.ts | 23 +++++------ 2 files changed, 30 insertions(+), 39 deletions(-) diff --git a/src/client/hud/layers/ControlPanel.ts b/src/client/hud/layers/ControlPanel.ts index f77684486..303aae100 100644 --- a/src/client/hud/layers/ControlPanel.ts +++ b/src/client/hud/layers/ControlPanel.ts @@ -347,19 +347,16 @@ export class ControlPanel extends LitElement implements Controller {
-
- ${greenPercent > 0 - ? html`
` - : ""} - ${orangePercent > 0 - ? html`
` - : ""} +
+
+
-
- ${greenPercent > 0 - ? html`
` - : ""} - ${orangePercent > 0 - ? html`
` - : ""} +
+
+
-
- ${greenPercent > 0 - ? html`
` - : ""} - ${orangePercent > 0 - ? html`
` - : ""} +
+
+