Show number fields with three decimals and snap dragging to the step
Number fields derived their display precision from `step`, so `step: 1` (X/Y/Z, width, height, font size) rendered a stored 100.234 as "100" — and because `onChange` parses the text, touching the field wrote the rounded value back into the project. `formatNumber` now renders every number with three decimals, independent of `step`, which is left to control the scrub and arrow-key increment only. Dragging now snaps to the increment's grid (`snapToStep`), so a scrub at `step: 1` always lands on whole numbers even from a fractional start, while Alt (x0.1) and the 0.1-step fields keep their precision. Typed values and arrow keys are untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
15ffcd5739
commit
6168df41f8
6 files changed
+104
-21
No files matched your search
@@ -8,6 +8,33 @@ export function centreY(containerHeight: number, itemHeight: number): number {
|
||||
return Math.round((containerHeight - itemHeight) / 2);
|
||||
}
|
||||
|
||||
/** Decimal places every number field shows. */
|
||||
export const NUMBER_DECIMALS = 3;
|
||||
|
||||
/**
|
||||
* Display text for a number. Always shows `decimals` places, so a value can never *look* like
|
||||
* a whole number when it is not: precision used to follow the field's step, which hid the
|
||||
* decimals that dragging in the viewport or a graph node had put into the value.
|
||||
* A value that rounds to zero never carries a minus sign.
|
||||
*/
|
||||
export function formatNumber(value: number, decimals = NUMBER_DECIMALS): string {
|
||||
const zero = (0).toFixed(decimals);
|
||||
const text = value.toFixed(decimals);
|
||||
return text === '-' + zero ? zero : text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds `value` onto the grid of `stepSize`, so scrubbing a field lands on clean values:
|
||||
* with step 1 on whole numbers, with step 0.1 on tenths. Needed because neither input is
|
||||
* whole – the pointer delta comes in fractional device pixels (a 150 % display yields
|
||||
* thirds) and the starting value may already be fractional from a viewport drag.
|
||||
* The `toFixed` pass removes binary-float noise (0.1 × 3 = 0.30000000000000004).
|
||||
*/
|
||||
export function snapToStep(value: number, stepSize: number): number {
|
||||
if (!(stepSize > 0) || !Number.isFinite(value)) return value;
|
||||
return Number((Math.round(value / stepSize) * stepSize).toFixed(NUMBER_DECIMALS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Zoom multiplier for one wheel event. Exponential, so scrolling up and back down by the same
|
||||
* amount lands exactly where it started. The caller clamps the result into its own range –
|
||||
|
||||
Reference in new issue
Block a user