Skip to content

Preserve ColorPicker hue for achromatic colors, fix stuck dragging state#529

Merged
slimbuck merged 3 commits into
mainfrom
color-dev
May 14, 2026
Merged

Preserve ColorPicker hue for achromatic colors, fix stuck dragging state#529
slimbuck merged 3 commits into
mainfrom
color-dev

Conversation

@slimbuck
Copy link
Copy Markdown
Member

Fixes #playcanvas/supersplat#892

Summary

Fixes three related bugs in ColorPicker:

  1. Hue resets to red when the selected color becomes achromatic. Dragging the saturation/value rect to white (top-left), black, or any gray, or typing an R=G=B value, would silently overwrite the stored hue with 0 because _rgb2hsv returns h=0, s=0 for achromatic input. The user's hue selection was lost on the next interaction. Fixes [playcanvas/supersplat#818](Selecting pure white resets hue in color picker supersplat#818) (supersplat's [PR #892](Preserve color picker hue when selecting white supersplat#892) is a downstream workaround that can be dropped once this lands). The fix gates the _colorHSV[0] assignment on hsv[1] > 0 in _setPickerColor, _callPicker, and _onChangeRgb. The partial sum !== 765 && sum !== 0 guard in _onChangeRgb (which only covered pure white / pure black) is replaced by the same general check, so mid-grays like (128,128,128) are now handled too.

  2. _dragging flag stuck true after typed input. _onChangeRgb sets _dragging = true when the user types into an R/G/B field, but nothing ever reset it. This made _setPickerColor a permanent no-op for the rest of the picker's lifetime (so external value updates stopped syncing to the overlay UI) and left the binding's historyCombine flag stuck on, breaking undo grouping. callbackHandle now resets _dragging and emits the matching picker:color:end after the throttled picker:color emit, and _onChangeRgb only emits picker:color:start on the leading edge so rapid typing produces properly paired start/end events.

  3. values setter called non-existent Array.prototype.equals. Any consumer that hit the array-of-arrays branch (e.g. multi-select bindings) would get a TypeError. Replaced with an inline length + element-wise comparison.

Test plan

  • npm run build:es6 clean
  • npm run lint:js clean
  • npm test — all 50 tests pass (no existing ColorPicker tests)
  • Manual (Storybook): in the ColorPicker story, dial in a blue hue, drag the SV-rect handle to top-left (white) — hue slider and rect background should stay blue, not snap to red. Repeat for bottom-left (black) and any mid-gray. Type 255,255,255 and #808080 directly into the fields — hue should also stay put. Sanity: typing #ff8800 should update the hue normally.
  • Manual (Storybook): after typing a value into an R/G/B field, programmatically update picker.value from the console — overlay UI should now reflect the change (previously it would stay frozen).
  • Confirm editor and supersplat consumers still work — neither subclasses ColorPicker or touches its protected internals (audited).

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes several ColorPicker interaction bugs by preserving hue across achromatic (gray) colors, correctly pairing typed-input “drag” start/end events, and removing reliance on a non-standard array equality helper.

Changes:

  • Preserve the last known hue when the selected color becomes achromatic (s === 0) so the UI doesn’t snap back to red.
  • Fix typed RGB input leaving _dragging stuck true by ensuring a corresponding “end” event is emitted after throttled updates.
  • Replace use of non-existent Array.prototype.equals in the values setter with an inline element-wise comparison.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/components/ColorPicker/index.ts
Comment thread src/components/ColorPicker/index.ts
Comment thread src/components/ColorPicker/index.ts
@slimbuck slimbuck merged commit 495f3f6 into main May 14, 2026
5 checks passed
@slimbuck slimbuck deleted the color-dev branch May 14, 2026 11:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants