diff --git a/src/components/floorplan-editor/views/FloorplanHeightPicker.test.tsx b/src/components/floorplan-editor/views/FloorplanHeightPicker.test.tsx index 9c047fe..f29f1fe 100644 --- a/src/components/floorplan-editor/views/FloorplanHeightPicker.test.tsx +++ b/src/components/floorplan-editor/views/FloorplanHeightPicker.test.tsx @@ -121,4 +121,22 @@ describe('FloorplanHeightPicker', () => restore(); }); + + it('thumb fill matches the tile colour at the picked height', () => + { + // h=0 is solid blue (#0065ff in COLORMAP). Re-render at a + // different height and assert the recorded thumb colour + // changes — i.e., the thumb tracks the band underneath. + const { rerender } = render( undefined } />); + + const colourAtZero = screen.getByTestId('height-thumb').getAttribute('data-thumb-color'); + + rerender( undefined } />); + + const colourAtThirteen = screen.getByTestId('height-thumb').getAttribute('data-thumb-color'); + + expect(colourAtZero).toBeTruthy(); + expect(colourAtThirteen).toBeTruthy(); + expect(colourAtZero).not.toBe(colourAtThirteen); + }); }); diff --git a/src/components/floorplan-editor/views/FloorplanHeightPicker.tsx b/src/components/floorplan-editor/views/FloorplanHeightPicker.tsx index 758dec8..b8dfd28 100644 --- a/src/components/floorplan-editor/views/FloorplanHeightPicker.tsx +++ b/src/components/floorplan-editor/views/FloorplanHeightPicker.tsx @@ -12,6 +12,26 @@ const TRACK_H = 260; const THUMB_DIAM = 28; const RAIL_GUTTER = 4; +/** + * Perceptual-luminance heuristic. Returns true if a hex colour is + * 'light enough' that black text reads better than white. Uses the + * Rec. 601 luma coefficients — good enough for a UI affordance, + * cheap to compute, no dep on a colour lib. + */ +const isLightColor = (hex: string): boolean => +{ + const c = hex.replace('#', ''); + + if(c.length !== 6) return true; + + const r = parseInt(c.slice(0, 2), 16); + const g = parseInt(c.slice(2, 4), 16); + const b = parseInt(c.slice(4, 6), 16); + const luma = (0.299 * r) + (0.587 * g) + (0.114 * b); + + return luma > 160; +}; + /** * Vertical brush-height slider. * @@ -107,6 +127,8 @@ export const FloorplanHeightPicker: FC = ({ selectedH, onSelect }) => }, [ isDragging, heightFromClientY, onSelect, selectedH ]); const thumbPct = ((HEIGHT_BRUSH_MAX - selectedH) / (count - 1)) * 100; + const thumbColor = tileFill({ h: selectedH, blocked: false }); + const thumbTextDark = isLightColor(thumbColor); return (
= ({ selectedH, onSelect }) => />
{ selectedH }