From 14aed0c1e3a20b54edd8347d2c47f267b0a63c29 Mon Sep 17 00:00:00 2001 From: Rrrrobert Date: Fri, 16 Oct 2026 14:21:59 -0400 Subject: [PATCH 1/2] Let the hue slider change white, gray and black New tags start white, which has no saturation, so moving the hue slider did nothing until a color was first picked in the square (gray and black behaved the same way). Picking a hue now gives a color with no saturation full saturation, and black full brightness, so the hue shows up straight away; grays keep their brightness. Colors that already have a hue are unchanged. Made with help from Claude --- public/color.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/color.js b/public/color.js index 9338439..b165455 100644 --- a/public/color.js +++ b/public/color.js @@ -281,6 +281,11 @@ const ColorPicker = { const pickHue = (evt) => { const rect = hueBar.getBoundingClientRect(); this.state[i].hue = Math.max(0, Math.min(1, (evt.clientX - rect.left) / rect.width)); + // White, gray and black have no saturation, so the hue alone + // wouldn't change them (e.g. the default white). Give them full + // saturation, and black full brightness, so the hue shows up. + if (this.state[i].s === 0) this.state[i].s = 1; + if (this.state[i].v === 0) this.state[i].v = 1; applyColor(); this.redraw(i); }; From ec91515ab6aac87f11793993723397dc09681e6a Mon Sep 17 00:00:00 2001 From: Rrrrobert Date: Fri, 16 Oct 2026 14:26:40 -0400 Subject: [PATCH 2/2] Keep the slider's hue for white, gray and black Replaces the previous approach: picking a hue no longer changes the selected color. Moving the hue slider redraws the square in the new hue, but the selected color is then written back to the hex box and re-read by setFromHex. White, gray and black have no hue, so re-reading them reset the hue to 0 and the square snapped back to red. That's why a color had to be picked in the square before the slider did anything. setFromHex now leaves the picker alone when it already shows that color, so the square keeps the slider's hue while the selected color (e.g. the default white) stays where it is. Made with help from Claude --- public/color.js | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/public/color.js b/public/color.js index b165455..074e250 100644 --- a/public/color.js +++ b/public/color.js @@ -229,7 +229,15 @@ const ColorPicker = { if (!hsv) return; this.state[i] = this.state[i] || {}; - [this.state[i].hue, this.state[i].s, this.state[i].v] = hsv; + const st = this.state[i]; + // Keep the picker as it is if it already shows this color. White, gray + // and black have no hue, so re-reading them would reset the hue the + // slider just set and snap the square back to red. + if (st.hue !== undefined && this.hsvToHex(st.hue, st.s, st.v) === this.hsvToHex(...hsv)) { + this.redraw(i); + return; + } + [st.hue, st.s, st.v] = hsv; this.redraw(i); }, @@ -281,11 +289,6 @@ const ColorPicker = { const pickHue = (evt) => { const rect = hueBar.getBoundingClientRect(); this.state[i].hue = Math.max(0, Math.min(1, (evt.clientX - rect.left) / rect.width)); - // White, gray and black have no saturation, so the hue alone - // wouldn't change them (e.g. the default white). Give them full - // saturation, and black full brightness, so the hue shows up. - if (this.state[i].s === 0) this.state[i].s = 1; - if (this.state[i].v === 0) this.state[i].v = 1; applyColor(); this.redraw(i); };