Skip to content

feat: adaptive background detection for dark mode support#23

Merged
RostiMelk merged 5 commits intomainfrom
feat/adaptive-background-detection
Feb 9, 2026
Merged

feat: adaptive background detection for dark mode support#23
RostiMelk merged 5 commits intomainfrom
feat/adaptive-background-detection

Conversation

@RostiMelk
Copy link
Member

@RostiMelk RostiMelk commented Feb 9, 2026

Replaces the hardcoded white background assumption in content detection by auto-detecting the background color from the image itself.

Transparent images — alpha-only content detection (unchanged from current behavior)
Opaque images — background color sampled from image edges

Adds backgroundColor prop as an explicit override fallback.

Usage

Works automatically — no config needed for opaque images:

<LogoSoup logos={logos} />

For explicit control (e.g. JPGs on a known dark page):

<LogoSoup logos={logos} backgroundColor={[20, 20, 20]} />

Also available on the hook:

const result = useLogoSoup({ logos, backgroundColor: [20, 20, 20] });

Closes #2

Replace hardcoded white (255,255,255) background assumption in content
detection with auto-detection from image perimeter pixels.

Two strategies, chosen automatically:
- Alpha-only: transparent PNGs skip color-distance filtering entirely
- Perimeter sampling: opaque images infer background via quantized
  color bucketing of edge pixels

Adds backgroundColor prop as explicit override fallback.
@vercel
Copy link

vercel bot commented Feb 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-logo-soup Building Building Preview, Comment Feb 9, 2026 7:42pm

Request Review

@github-actions
Copy link

github-actions bot commented Feb 9, 2026

Benchmark Comparison: main vs feat/adaptive-background-detection

Threshold: 5%+ change, >100us absolute delta, and statistically significant (p<0.05).

Benchmark main feat/adaptive-background-detection Change p-value Verdict
content detection (1 logo) 34.35 us 35.98 us +4.8% 0.356 unchanged
render pass (20 logos) 861 ns 1.02 us +18.5% <0.001 *** unchanged
mount 20 logos (no detection) 2.99 us 2.92 us -2.3% 0.002 ** unchanged
mount 20 logos (defaults) 797.75 us 833.74 us +4.5% <0.001 *** unchanged

No regressions detected.

Feature cost breakdown

How expensive are individual features? Measured on this run's HEAD commit.

Feature On Off Cost Sig
densityAware: true vs false 33.12 us 31.36 us ~same 0.116
alignBy: visual-center-y vs bounds 901 ns 56 ns 16× slower <0.001 ***
cropToContent: true vs false 2.14 ms 74 ns 2.14 ms <0.001 ***
layout update: full mount vs cached 825.60 us 2.10 us 393× slower <0.001 ***

Full benchmark output in the CI job logs.

The corner-first fast path misidentified logo content as background
when logos extended to the corners, causing sizing regressions.

Restores the first commit's logic (full perimeter scan, alphaOnly for
transparent images) with typed arrays instead of Map for bucketing.
- Inverted SVGs (transparent, light content) and JPG test logos
- Dark Mode, JPG, and Comparison stories under LogoSoup group
- Shared StoryLogoSoup wrapper with debug controls
- Consolidated argTypes, defaults, and types in shared.tsx
- alphaOnly path for transparent images, color distance for opaque
- min(a, sqrt(distSq)) opacity for opaque density normalization
@RostiMelk RostiMelk marked this pull request as ready for review February 9, 2026 19:35
BackgroundColor type accepts hex, rgb(), hsl(), named colors, or
[r, g, b] tuples. CSS strings are resolved via a 1×1 canvas.
@RostiMelk RostiMelk merged commit 449a177 into main Feb 9, 2026
8 of 12 checks passed
@RostiMelk RostiMelk mentioned this pull request Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dark Mode Support

1 participant