← back to Dw Photo Capture
color-widen: add min param — guarantee >=N results via nearest-neighbor fallback when the band is thin
0d6c355e88bfec17d40393b871ce4a35b48de1e5 · 2026-07-16 11:40:44 -0700 · Steve
Files touched
Diff
commit 0d6c355e88bfec17d40393b871ce4a35b48de1e5
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Jul 16 11:40:44 2026 -0700
color-widen: add min param — guarantee >=N results via nearest-neighbor fallback when the band is thin
---
server.js | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/server.js b/server.js
index def8fff..09443b6 100644
--- a/server.js
+++ b/server.js
@@ -1059,24 +1059,27 @@ const appHandler = (req, res) => {
if (!hex) return send(res, 400, { err: 'hex required (#rrggbb)' }, CORS);
const k = Math.max(1, Math.min(parseInt(p.k, 10) || 240, 400));
const ceil = Math.max(5, Math.min(Number(p.ceiling) || 15, 25)); // % ≈ ΔE76 ceiling
+ const min = Math.max(0, Math.min(parseInt(p.min, 10) || 0, 400)); // guarantee at least this many
try {
const idx = loadColorIndex(); // cached, loaded once
const target = hexToLab(hex);
- const within = [];
- for (let i = 0; i < idx.length; i++) {
+ const scored = []; // ΔE for EVERY product, so we can
+ for (let i = 0; i < idx.length; i++) { // fall back to nearest-N when the band is thin
const it = idx[i];
const dl = it.l - target.l, da = it.a - target.a, db = it.b - target.b;
- const de = Math.sqrt(dl * dl + da * da + db * db);
- if (de <= ceil) within.push({ it, de });
+ scored.push({ it, de: Math.sqrt(dl * dl + da * da + db * db) });
}
- within.sort((x, y) => x.de - y.de); // nearest first
- const results = within.slice(0, k).map(w => ({
+ scored.sort((x, y) => x.de - y.de); // nearest first
+ let sel = scored.filter(s => s.de <= ceil); // within the 15% band
+ const withinCeiling = sel.length;
+ if (sel.length < min) sel = scored.slice(0, min); // thin band → expand to the nearest `min`
+ const results = sel.slice(0, k).map(w => ({
handle: w.it.h, title: w.it.t, vendor: w.it.v,
hex: w.it.x, image: w.it.i, delta_e: Math.round(w.de * 10) / 10
}));
return send(res, 200, {
- ok: true, hex, tolerance_pct: ceil / 100,
- delta_e_ceiling: ceil, total_in_tolerance: within.length, results
+ ok: true, hex, tolerance_pct: ceil / 100, delta_e_ceiling: ceil, min,
+ total_in_tolerance: withinCeiling, returned: results.length, results
}, CORS);
} catch (e) {
return send(res, 503, { ok: false, err: 'color index unavailable', results: [] }, CORS);
← e2c9e01 add /apps/color-widen route: tunable ΔE band (default 15%) f
·
back to Dw Photo Capture
·
color-index: carry product_type through builder + both /apps 8112eaf →