Files
comunidadhll/ai/tasks/done/TASK-259-analyze-weapon-icon-canvas-and-normalization-strategy.md
2026-06-15 22:17:13 +02:00

16 KiB

id, title, status, type, team, supporting_teams, roadmap_item, priority
id title status type team supporting_teams roadmap_item priority
TASK-259 Analyze weapon icon canvas and normalization strategy review research Frontend Senior
Experto en interfaz
frontend-current-match medium

TASK-259 - Analyze weapon icon canvas and normalization strategy

Goal

Analyze why weapon icons in the current match combat feed still look visually uneven after TASK-258, without editing weapon assets or changing runtime behavior. This task is kept in review because the analysis should be accepted before TASK-260 implementation starts.

Context

TASK-258 made the combat feed weapon slot more stable in CSS, but several weapons still have different visual weight. The likely cause is not only the CSS frame: the source weapon files use different canvas ratios, viewBox sizes and internal whitespace.

Files Read First

  • ai/architecture-index.md
  • ai/repo-context.md
  • ai/task-template.md
  • ai/orchestrator/frontend-senior.md
  • frontend/assets/js/current-match-weapon-icons.js
  • frontend/assets/js/partida-actual.js
  • frontend/assets/css/historico.css
  • frontend/assets/img/weapons/

Analysis

Resolver And Render Path

The current match weapon resolver is frontend/assets/js/current-match-weapon-icons.js.

  • Runtime base path: ./assets/img/weapons/black/
  • Runtime lookup: globalThis.HLL_VIETNAM_CURRENT_MATCH_WEAPON_ICONS.lookup
  • Unknown fallback: precision_strike_black.svg

Resolved files for the required sample, using the real HLL_VIETNAM_CURRENT_MATCH_WEAPON_ICONS.lookup normalization:

Requested weapon Resolved label Resolved file Resolved URL
M1 GARAND M1 GARAND m1_garand_black.svg ./assets/img/weapons/black/m1_garand_black.svg
GEWEHR 43 GEWEHR 43 gewehr_black.svg ./assets/img/weapons/black/gewehr_black.svg
KARABINER 98K KARABINER 98K kar98k_black.svg ./assets/img/weapons/black/kar98k_black.svg
MG42 MG42 mg42_black.svg ./assets/img/weapons/black/mg42_black.svg
BROWNING M1919 BROWNING M1919 browning_m1919_black.svg ./assets/img/weapons/black/browning_m1919_black.svg
M2 AP MINE M2 AP MINE m2_ap_mine_black.svg ./assets/img/weapons/black/m2_ap_mine_black.svg
MP40 MP40 mp40_black.svg ./assets/img/weapons/black/mp40_black.svg
PANZERSCHRECK PANZERSCHRECK panzerschreck_black.svg ./assets/img/weapons/black/panzerschreck_black.svg
75MM CANNON / cannon equivalent 75MM CANNON [PAK 40] pak_40_75mm_black.svg ./assets/img/weapons/black/pak_40_75mm_black.svg

The combat feed renderer is frontend/assets/js/partida-actual.js.

  • renderKillFeedRow() resolves event.weapon through resolveKillFeedWeapon().
  • renderKillFeedWeaponIcon() emits:
    • .current-match-killfeed__weapon-icon-frame
    • .current-match-killfeed__weapon-icon
    • fallback ? span on image error
  • The generated img keeps fixed HTML attributes width="88" and height="32", but TASK-258 CSS overrides the rendered sizing with width: auto, height: auto, max-width and max-height.

Asset Types

Repository asset inventory under frontend/assets/img/weapons/:

Area Type Count Notes
frontend/assets/img/weapons/ PNG 38 Legacy/root weapon assets, not used by current match black resolver.
frontend/assets/img/weapons/black/ SVG 123 Used by current match combat feed resolver.
frontend/assets/img/weapons/red/ SVG 38 Not used by current match black resolver.
frontend/assets/img/weapons/white/ SVG 38 Not used by current match black resolver.
frontend/assets/img/weapons/black - copia/ SVG 122 Untracked copy present in working tree, not used by resolver.

For the combat feed path analyzed here, the resolved assets are SVG. No WebP weapon assets were found in the resolver path.

CSS Application Check

TASK-258 CSS applies to the DOM generated by partida-actual.js.

  • JS emits .current-match-killfeed__row, .current-match-killfeed__weapon, .current-match-killfeed__weapon-icon-frame and .current-match-killfeed__weapon-icon.
  • historico.css defines those selectors directly.
  • A static selector search found no later conflicting definitions outside the expected media queries in historico.css.
  • Browser computed-style measurement was run against frontend/partida-actual.html loaded through file://, with test rows injected into the real #current-match-feed-list. The backend fetches fail in this diagnostic mode because file:// cannot call /api/..., but the DOM, CSS and local SVG loading path are the same static frontend path under inspection.

This means the remaining visual mismatch is not explained by a missing selector. CSS can constrain the frame, but it cannot remove transparent/internal whitespace inside each SVG viewBox.

Computed values observed at a 1366px viewport:

DOM element Selector Computed values Overwrite finding
Weapon wrapper .current-match-killfeed__weapon display: grid, width: 112px, min-height: 48px, actual row sample height 58.2031px Matches TASK-258 CSS. No conflicting computed value observed.
Icon frame .current-match-killfeed__weapon-icon-frame width: 96px, height: 36px, padding: 3px 7px, overflow: hidden Matches TASK-258 CSS. No conflicting computed value observed.
Image .current-match-killfeed__weapon-icon max-width: 82px, max-height: 26px, object-fit: contain, object-position: 50% 50% Matches TASK-258 CSS. No conflicting computed value observed.

Computed image render sizes from the same DOM sample:

Weapon Natural image size from browser Computed image size Why it still differs visually
M1 GARAND 1448x1086 34.6562x26px SVG ratio 1.33 and large vertical whitespace force browser to cap by height; visible rifle becomes very small.
GEWEHR 43 2172x724 78x26px SVG ratio 3.00 uses the fixed slot more effectively.
KARABINER 98K 1448x1086 34.6562x26px Same 1.33 canvas family as M1 Garand; rendered width is less than half of 3.00 assets.
MG42 1448x1086 34.6562x26px Same computed box as rifles, but silhouette has more vertical mass inside its canvas.
BROWNING M1919 1254x1254 26x26px Square canvas makes the rendered box even narrower.
M2 AP MINE 1254x1254 26x26px Square canvas and compact object need semantic tuning even after crop.
MP40 2172x724 78x26px Wide 3.00 canvas fills much more slot width.
PANZERSCHRECK 2172x724 78x26px Wide 3.00 canvas fills much more slot width and has heavy silhouette.
75MM CANNON [PAK 40] 2172x724 78x26px Wide canvas plus large silhouette dominates compared with rifles.

Asset Measurements

The sample was measured with a one-off inline Node script. For SVGs, the script parsed width, height, viewBox, aspect ratio and approximate path bounds to estimate occupied canvas area and margins. No script file was created.

Distribution of viewBox aspect ratios in frontend/assets/img/weapons/black/:

Ratio Count
1.00 29
1.33 39
1.50 1
1.78 3
3.00 51

Representative asset sample:

| Weapon | Resolved file | Type | Width / height / viewBox | Ratio | Approx. silhouette occupancy | Canvas / margin observation | Suspicion | | --- | --- | --- | --- | ---: | --- | --- | | M1 GARAND | m1_garand_black.svg | SVG | width 1448, height 1086, viewBox 0 0 1448 1086 | 1.33 | approx. 90.7% x 22.7% | Long rifle has large top/bottom margins, roughly 417px top and 423px bottom. | margen interno excesivo | | GEWEHR 43 | gewehr_black.svg | SVG | width 2172, height 724, viewBox 0 0 2172 724 | 3.00 | approx. 88.4% x 41.7% | Wide canvas fits rifle shape better, with moderate vertical margin. | OK / mild tuning | | KARABINER 98K | kar98k_black.svg | SVG | width 1448, height 1086, viewBox 0 0 1448 1086 | 1.33 | approx. 94.5% x 21.9% | Long rifle has large top/bottom margins, roughly 417px top and 431px bottom. | margen interno excesivo | | MG42 | mg42_black.svg | SVG | width 1448, height 1086, viewBox 0 0 1448 1086 | 1.33 | approx. 96.0% x 39.4% | Same canvas family as rifles, but silhouette is almost twice as tall. | necesita normalizacion | | BROWNING M1919 | browning_m1919_black.svg | SVG | width 1254, height 1254, viewBox 0 0 1254 1254 | 1.00 | approx. 90.5% x 36.2% | Square canvas forces the browser to render at 26x26px under TASK-258 max-height. | necesita normalizacion | | M2 AP MINE | m2_ap_mine_black.svg | SVG | width 1254, height 1254, viewBox 0 0 1254 1254 | 1.00 | approx. 92.3% x 45.9% | Square canvas and compact subject are not comparable with long weapons. | necesita tuning por arma | | MP40 | mp40_black.svg | SVG | width 2172, height 724, viewBox 0 0 2172 724 | 3.00 | approx. 85.0% x 76.1% | Wide canvas fills slot width, but silhouette is much taller than rifles. | necesita normalizacion | | PANZERSCHRECK | panzerschreck_black.svg | SVG | width 2172, height 724, viewBox 0 0 2172 724 | 3.00 | approx. 90.9% x 56.2% | Wide launcher fills slot width and has heavy silhouette. | necesita normalizacion | | 75MM CANNON [PAK 40] | pak_40_75mm_black.svg | SVG | width 2172, height 724, viewBox 0 0 2172 724 | 3.00 | approx. 94.7% x 69.2% | Cannon occupies much of the canvas and dominates the same CSS frame. | necesita tuning por arma |

Diagnosis

The issue is asset canvas/viewBox normalization, not a selector failure.

  • Selector CSS problem: not observed. Rendered classes and CSS selectors match.
  • CSS overwritten problem: not observed in static scan. Only expected media query variants were found.
  • Asset canvas/viewBox/internal whitespace problem: confirmed. The same CSS frame receives SVGs with ratios from 1.00 to 3.00 and very different occupied-height percentages.

CSS from TASK-258 is useful and should remain because it stabilizes the combat feed frame, prevents layout jumps and gives a consistent maximum slot. It is not sufficient to equalize perceived visual mass across assets with very different canvas geometry. The browser computed data shows the practical failure mode: a 1.33-ratio SVG renders at about 34.6562x26px, a 1.00-ratio SVG renders at 26x26px, and a 3.00-ratio SVG renders at 78x26px under the same TASK-258 image constraints.

Technical Options

A. Create normalized derived assets in a new folder

Create derived files such as frontend/assets/img/weapons/normalized-black/ from the existing black SVGs, preserving originals. Each derived asset should crop or normalize the viewBox to the visible silhouette plus controlled padding, then be tested in the existing frame.

Pros:

  • Does not mutate original assets.
  • Keeps runtime CSS simple.
  • Produces stable visual results across long rifles, mines, launchers and cannons.

Cons:

  • Requires a generation/QA pass.
  • Needs resolver switch in a later task.

B. Adjust viewBox of existing SVGs

Edit current SVG viewBoxes in frontend/assets/img/weapons/black/.

Pros:

  • Directly fixes source geometry.

Cons:

  • Mutates original assets.
  • Higher review risk.
  • Harder to revert if originals are needed for other contexts.

C. Create a manifest of tuning by weapon

Add a tuning manifest with per-icon classes or variables, for example scale factors for rifles, mines and heavy weapons.

Pros:

  • Avoids asset generation.
  • Can handle semantic outliers such as mines or vehicle guns.

Cons:

  • Becomes manual and brittle.
  • Still cannot remove transparent canvas; it only counter-scales it.

D. Keep CSS and accept differences

Do nothing beyond TASK-258.

Pros:

  • No new files or resolver changes.

Cons:

  • Does not address the reported visual inconsistency.
  • Long thin rifles and square/heavy assets will keep reading as uneven.

Recommendation

Preferred path: A. Create normalized derived assets in a new folder, then switch the current match resolver to that folder only after visual QA.

Do not touch originals in frontend/assets/img/weapons/black/ during the implementation task. Generate derived normalized black SVGs from the existing resolver set, with a consistent target canvas strategy:

  • Preserve original source files untouched.
  • Crop each SVG viewBox to visible path bounds plus controlled padding.
  • Keep a consistent output viewport family for horizontal weapons.
  • Define explicit exceptions or per-asset scale targets for mines, artillery, vehicles and support actions.
  • Add a small manifest only for unavoidable semantic outliers after normalization, not as the primary fix.

Proposed TASK-260

Create TASK-260-create-derived-normalized-current-match-weapon-icons.md with this scope:

  1. Generate derived normalized SVGs in a new folder, for example frontend/assets/img/weapons/current-match-normalized-black/.
  2. Do not modify files under frontend/assets/img/weapons/black/.
  3. Start with the nine measured files in this task and normalize them to comparable visible silhouette occupancy before expanding.
  4. Crop each SVG viewBox to visible path bounds plus controlled padding, then apply a target output strategy that prevents rifles from shrinking to 34.6562x26px while wide assets render at 78x26px.
  5. Define explicit handling for semantic outliers: mines, cannons, tanks, support effects and vehicle icons should not be forced to the same perceived mass as long rifles.
  6. Include a repeatable local one-off or support script only if it is intended to be committed as platform/tooling; otherwise run it outside commit.
  7. Expand to all files referenced by CURRENT_MATCH_BLACK_WEAPON_ICON_FILES.
  8. Switch CURRENT_MATCH_BLACK_WEAPON_ICON_PATH only after derived files exist and spot checks pass.
  9. Keep TASK-258 CSS unless browser QA proves a minor frame adjustment is needed.

Suggested validation for TASK-260:

  • node --check frontend/assets/js/current-match-weapon-icons.js
  • node --check frontend/assets/js/partida-actual.js
  • Verify all resolver files exist in the new normalized folder.
  • Browser spot check of combat feed icons at desktop and mobile widths.
  • git status --short --untracked-files=all
  • Confirm original frontend/assets/img/weapons/black/ files are unchanged.

Validation

  • Read required repository context and frontend role guidance.
  • Inspected the resolver in frontend/assets/js/current-match-weapon-icons.js.
  • Inspected combat feed rendering in frontend/assets/js/partida-actual.js.
  • Inspected TASK-258 CSS selectors in frontend/assets/css/historico.css.
  • Ran a one-off inline Node measurement script for representative SVG dimensions, viewBox ratios and approximate path occupancy.
  • Resolved the required sample through the actual runtime lookup in current-match-weapon-icons.js.
  • Ran browser computed-style diagnostics with a temporary Playwright install outside the repo, loading frontend/partida-actual.html through file:// and injecting combat-feed test rows into the real DOM.
  • Ran a static selector search for combat feed weapon classes.
  • Ran git status --short --untracked-files=all.
  • Did not run node --check frontend/assets/js/partida-actual.js because no JS file was modified.
  • No integration tests were relevant for this documentation-only analysis.

Outcome

TASK-259 is ready for review as an analysis and decision task. It should not be treated as closed until the analysis is accepted. The remaining uneven icon sizing is caused by asset geometry differences: mixed SVG canvas ratios, large internal whitespace and different visible silhouette occupancy. CSS from TASK-258 applies and should remain, but it is not sufficient as the final normalization mechanism.

Modified file for this task:

  • ai/tasks/done/TASK-259-analyze-weapon-icon-canvas-and-normalization-strategy.md

Explicitly not modified:

  • frontend/assets/js/partida-actual.js
  • frontend/assets/js/current-match-weapon-icons.js
  • frontend/assets/css/historico.css
  • frontend/assets/img/weapons/
  • backend, scheduler, RCON, server configuration, ai/system-metrics.md, tmp/, TASK-204 and unrelated prior changes.

Change Budget

  • Files modified by this task: 1
  • Product code modified by this task: 0
  • Asset files modified by this task: 0