@tremolo-ui/functions 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -4,14 +4,18 @@
4
4
  */
5
5
  declare function clamp(value: number, min: number, max: number): number;
6
6
  /**
7
- * Normalize the value from 0 to 1
7
+ * Normalize the value from 0 to 1, spreading the range evenly.
8
+ *
9
+ * This is the linear mapping and takes no curve of its own; a `Scale` builds
10
+ * whatever curve it needs on top of it.
8
11
  */
9
- declare function normalizeValue(rawValue: number, min: number, max: number, skew?: number): number;
12
+ declare function normalizeValue(value: number, min: number, max: number): number;
10
13
  /**
11
- * Convert normalized values back to raw values.
14
+ * Convert normalized values back to raw values, spreading the range evenly.
15
+ *
16
+ * The inverse of {@link normalizeValue}.
12
17
  */
13
- declare function rawValue(normalizedValue: number, min: number, max: number, skew?: number): number;
14
- declare function skewWithCenterValue(centerValue: number, min: number, max: number): number;
18
+ declare function rawValue(normalizedValue: number, min: number, max: number): number;
15
19
  declare function stepValue(value: number, step: number): number;
16
20
  declare function toFixed(x: number, fractionDigits?: number): number;
17
21
  declare function integerPart(x: number | string): string | undefined;
@@ -22,6 +26,157 @@ declare function mapValue(value: number, inMin: number, inMax: number, outMin: n
22
26
  declare function dbToGain(db: number): number;
23
27
  declare function gainToDb(gain: number): number;
24
28
  //#endregion
29
+ //#region src/types.d.ts
30
+ /**
31
+ * Options for setting the amount of keyboard and mouse wheel changes.
32
+ */
33
+ type InputEventOption = ['normalized' | 'raw', number];
34
+ //#endregion
35
+ //#region src/scales.d.ts
36
+ /**
37
+ * How a value is distributed across the travel of a control.
38
+ *
39
+ * `normalize` and `denormalize` are inverses of each other: the position is
40
+ * 0 at `min` and 1 at `max`, and everything in between is up to the scale.
41
+ *
42
+ * `min` and `max` are arguments rather than baked into the scale, so a scale
43
+ * holds no state and can be a module level constant. Passing the same object
44
+ * on every render therefore costs nothing.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * exponentialScale.denormalize(0.5, 20, 20000) // 632.45…
49
+ * ```
50
+ */
51
+ interface Scale {
52
+ /** Value to its position on the travel, 0-1. */
53
+ normalize: (value: number, min: number, max: number) => number;
54
+ /** Position on the travel, 0-1, back to a value. */
55
+ denormalize: (position: number, min: number, max: number) => number;
56
+ }
57
+ /**
58
+ * Equal travel gives an equal change in value.
59
+ *
60
+ * The right default for anything already linear in perception: dB values,
61
+ * pan, percentages, MIDI note numbers, semitones.
62
+ */
63
+ declare const linearScale: Scale;
64
+ /**
65
+ * The power law of JUCE's `NormalisableRange::skew`, applied to `value - min`.
66
+ *
67
+ * Use it when the value has to agree with a JUCE or iPlug2 parameter — a
68
+ * plugin UI in a WebView, say, where the knob must sit exactly where the
69
+ * host's automation curve puts it. {@link skewWithCenterValue} gives the
70
+ * factor that places a chosen value at the middle of the travel.
71
+ *
72
+ * `skew < 1` gives the lower end more travel, `skew > 1` the upper end.
73
+ *
74
+ * For new designs prefer {@link exponentialScale} or {@link curveScale}: the
75
+ * slope of this curve is either zero or infinite at `min`, so the bottom of
76
+ * the range is a dead zone or jumps.
77
+ *
78
+ * @param skew the JUCE skew factor
79
+ */
80
+ declare function skewScale(skew: number): Scale;
81
+ /**
82
+ * The skew factor for {@link skewScale} that puts `centerValue` at the middle
83
+ * of the travel — JUCE's `NormalisableRange::setSkewForCentre`.
84
+ */
85
+ declare function skewWithCenterValue(centerValue: number, min: number, max: number): number;
86
+ /**
87
+ * Equal travel gives an equal *ratio*, so an octave — or a percentage — takes
88
+ * the same distance wherever it falls.
89
+ *
90
+ * The scale for frequency (a filter cutoff over 20-20000 Hz), free running
91
+ * rates, and delay times.
92
+ *
93
+ * Requires `min` and `max` to be non-zero and of the same sign, since no
94
+ * ratio reaches zero or crosses it. Use {@link curveScale} for a range that
95
+ * starts at 0.
96
+ */
97
+ declare const exponentialScale: Scale;
98
+ /**
99
+ * An exponential bend that still passes exactly through `min` and `max`, so
100
+ * unlike {@link exponentialScale} it works on a range that starts at 0 or
101
+ * crosses it, and unlike {@link skewScale} its slope is neither zero nor
102
+ * infinite at either end.
103
+ *
104
+ * The general purpose taper, and the same family as the curve of an envelope
105
+ * segment (SuperCollider's `CurveWarp`).
106
+ *
107
+ * - `curve > 0` gives the lower end more travel — envelope times from 0 ms,
108
+ * delay times, anything that wants fine control near the bottom
109
+ * - `curve < 0` gives the upper end more travel — a volume fader over
110
+ * -60..+6 dB that should be precise around 0 dB
111
+ * - near 0 it is indistinguishable from {@link linearScale}, and is treated
112
+ * as linear to avoid dividing by zero
113
+ *
114
+ * {@link curveWithCenterValue} gives the curve that places a chosen value at
115
+ * the middle of the travel.
116
+ *
117
+ * @param curve how hard the curve bends, and in which direction
118
+ */
119
+ declare function curveScale(curve: number): Scale;
120
+ /**
121
+ * {@link skewScale} mirrored about the middle of the range, so both halves
122
+ * bend the same way — JUCE's `symmetricSkew`.
123
+ *
124
+ * For a bipolar control whose centre matters: detune over -100..+100 cents,
125
+ * or a bipolar filter envelope amount, where the fine adjustment is around 0
126
+ * rather than at either end.
127
+ *
128
+ * `skew < 1` gives the middle more travel, `skew > 1` the two ends.
129
+ *
130
+ * @param skew the JUCE skew factor
131
+ */
132
+ declare function symmetricSkewScale(skew: number): Scale;
133
+ /**
134
+ * The curve for {@link curveScale} that puts `centerValue` at the middle of
135
+ * the travel — the counterpart of {@link skewWithCenterValue}.
136
+ */
137
+ declare function curveWithCenterValue(centerValue: number, min: number, max: number): number;
138
+ /**
139
+ * How a value is scaled: the range it lives in, how it is rounded, and how it
140
+ * is distributed across the travel.
141
+ *
142
+ * `AxisOptions` of `@tremolo-ui/dom` extends this, so a drag and a
143
+ * wheel / keyboard nudge run the same value pipeline.
144
+ */
145
+ interface ValueRange {
146
+ min: number;
147
+ max: number;
148
+ /**
149
+ * Rounding applied to the value. Left unrounded when omitted.
150
+ */
151
+ step?: number;
152
+ /**
153
+ * How the value is distributed across the travel.
154
+ *
155
+ * @default linearScale
156
+ */
157
+ scale?: Scale;
158
+ }
159
+ /**
160
+ * Move a value by an amount of input, as reported by a wheel or an arrow key.
161
+ *
162
+ * The pipeline matches `createDragValue` of `@tremolo-ui/dom`: scale, then
163
+ * step, then clamp. Which key or which sign of `deltaY` counts as which
164
+ * direction is left to the caller, since it differs per component.
165
+ *
166
+ * @param direction which way, and how many times, to apply the option. The
167
+ * size of one step is `option[1]`, so this is normally `1` or `-1`.
168
+ *
169
+ * @example
170
+ * // ArrowDown on a slider whose keyboard option is ['raw', 1]
171
+ * applyDelta(value, -1, keyboard, { min, max, step, scale })
172
+ */
173
+ declare function applyDelta(value: number, direction: number, [mode, amount]: InputEventOption, {
174
+ min,
175
+ max,
176
+ step,
177
+ scale
178
+ }: ValueRange): number;
179
+ //#endregion
25
180
  //#region src/midi.d.ts
26
181
  declare const whiteKeys: readonly ["A", "B", "C", "D", "E", "F", "G"];
27
182
  type WhiteKey = (typeof whiteKeys)[number];
@@ -62,12 +217,168 @@ declare function isBlackKey(note: number | string): boolean;
62
217
  * @returns frequency [Hz]
63
218
  */
64
219
  declare function noteToFrequency(note: number | string, detune?: number, a4?: number): number;
220
+ /**
221
+ * Semitones above the root, for each supported scale.
222
+ *
223
+ * Every entry starts at 0 and stays inside one octave, so a scale is a set of
224
+ * pitch classes rather than a set of notes: {@link inScale} compares against
225
+ * it with the octave taken out.
226
+ *
227
+ * `ionian` and `aeolian` are the same sets as `major` and `naturalMinor`; both
228
+ * spellings are here because both are what someone reaches for depending on
229
+ * whether they are thinking in keys or in modes.
230
+ */
231
+ declare const scaleIntervals: {
232
+ readonly major: readonly [0, 2, 4, 5, 7, 9, 11];
233
+ readonly naturalMinor: readonly [0, 2, 3, 5, 7, 8, 10];
234
+ readonly harmonicMinor: readonly [0, 2, 3, 5, 7, 8, 11];
235
+ readonly melodicMinor: readonly [0, 2, 3, 5, 7, 9, 11];
236
+ readonly ionian: readonly [0, 2, 4, 5, 7, 9, 11];
237
+ readonly dorian: readonly [0, 2, 3, 5, 7, 9, 10];
238
+ readonly phrygian: readonly [0, 1, 3, 5, 7, 8, 10];
239
+ readonly lydian: readonly [0, 2, 4, 6, 7, 9, 11];
240
+ readonly mixolydian: readonly [0, 2, 4, 5, 7, 9, 10];
241
+ readonly aeolian: readonly [0, 2, 3, 5, 7, 8, 10];
242
+ readonly locrian: readonly [0, 1, 3, 5, 6, 8, 10];
243
+ readonly majorPentatonic: readonly [0, 2, 4, 7, 9];
244
+ readonly minorPentatonic: readonly [0, 3, 5, 7, 10];
245
+ readonly blues: readonly [0, 3, 5, 6, 7, 10];
246
+ readonly wholeTone: readonly [0, 2, 4, 6, 8, 10];
247
+ readonly chromatic: readonly [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
248
+ };
249
+ type ScaleName = keyof typeof scaleIntervals;
250
+ /**
251
+ * Whether a note belongs to a scale, regardless of the octave either sits in.
252
+ *
253
+ * @param note noteNumber: 0 ~ 127 or noteName e.g. 'C3'
254
+ * @param root the note the scale is built on, in the same two forms
255
+ *
256
+ * @example
257
+ * ```ts
258
+ * inScale('F#4', 'D3', 'major') // true
259
+ * ```
260
+ */
261
+ declare function inScale(note: number | string, root: number | string, name: ScaleName): boolean;
262
+ /**
263
+ * The notes of a scale, ascending from `root`.
264
+ *
265
+ * The octave above the root is not included: ask for more `octaves` instead, so
266
+ * that concatenating the result of two calls does not repeat a note.
267
+ *
268
+ * @param root noteNumber: 0 ~ 127 or noteName e.g. 'C3'
269
+ * @param octaves how many octaves to cover
270
+ *
271
+ * @example
272
+ * ```ts
273
+ * scaleNotes('C3', 'majorPentatonic') // [48, 50, 52, 55, 57]
274
+ * ```
275
+ */
276
+ declare function scaleNotes(root: number | string, name: ScaleName, octaves?: number): number[];
65
277
  //#endregion
66
- //#region src/types.d.ts
278
+ //#region src/piano.d.ts
279
+ type NoteRange = {
280
+ first: number;
281
+ last: number;
282
+ };
67
283
  /**
68
- * Options for setting the amount of keyboard and mouse wheel changes.
284
+ * `[noteRange.first, noteRange.first + 1, ..., noteRange.last]`
69
285
  */
70
- type InputEventOption = ['normalized' | 'raw', number];
286
+ declare function getNoteRangeArray(noteRange: NoteRange): number[];
287
+ /**
288
+ * The geometry of a drawn keyboard.
289
+ *
290
+ * One description is shared by the drawing and the hit testing, so a key cannot
291
+ * be drawn somewhere other than where it responds.
292
+ */
293
+ interface PianoLayout {
294
+ noteRange: NoteRange;
295
+ /** Width of a white key, excluding {@link PianoLayout.keyGap}. */
296
+ whiteKeyWidth: number;
297
+ /**
298
+ * Space between two white keys. Part of the slot a white key occupies, so it
299
+ * still belongs to one of the keys for the purpose of hit testing.
300
+ *
301
+ * @default 1
302
+ */
303
+ keyGap?: number;
304
+ /**
305
+ * Width of a black key, as a fraction of {@link PianoLayout.whiteKeyWidth}.
306
+ *
307
+ * @default 0.65
308
+ */
309
+ blackKeyWidthRatio?: number;
310
+ /**
311
+ * Height of a black key, as a fraction of the height of the keyboard.
312
+ *
313
+ * @default 0.6
314
+ */
315
+ blackKeyHeightRatio?: number;
316
+ }
317
+ /** Width of a black key in pixels. */
318
+ declare function blackKeyWidth(layout: PianoLayout): number;
319
+ /** Width of the whole keyboard in pixels. */
320
+ declare function pianoWidth(layout: PianoLayout): number;
321
+ /**
322
+ * Offset of the left edge of a key from the left edge of the keyboard, in
323
+ * pixels.
324
+ *
325
+ * Notes outside `noteRange` are placed too, so the value is negative below
326
+ * `noteRange.first`.
327
+ */
328
+ declare function notePosition(note: number, layout: PianoLayout): number;
329
+ /**
330
+ * The note drawn at a point, or null where there is none.
331
+ *
332
+ * Black keys are tested first, so they win where they overlap a white one. A
333
+ * white key covers its gap as well as its width, so the whole width of the
334
+ * keyboard belongs to some key and a click cannot fall between two.
335
+ *
336
+ * @param x offset from the left edge of the keyboard, in pixels
337
+ * @param y offset from its top edge, in pixels
338
+ * @param height height of the keyboard, in pixels
339
+ */
340
+ declare function noteAt(x: number, y: number, height: number, layout: PianoLayout): number | null;
341
+ //#endregion
342
+ //#region src/unit.d.ts
343
+ /**
344
+ * Units a value can be displayed in, as `[symbol, scale]` pairs ordered from
345
+ * the smallest scale up. A value is shown in the largest unit that does not
346
+ * exceed it.
347
+ *
348
+ * @example
349
+ * [['Hz', 1], ['kHz', 1000]]
350
+ * [['ms', 1], ['s', 1000]]
351
+ */
352
+ type Units = [string, number][];
353
+ /**
354
+ * Pick the unit a value is displayed in: the largest one whose scale does not
355
+ * exceed the magnitude of the value.
356
+ */
357
+ declare function selectUnit(units: Units, value: number): [string, number];
358
+ /**
359
+ * Render a value as text, in the unit that suits its magnitude.
360
+ *
361
+ * @param units a single symbol appended as-is, or a list to choose from.
362
+ * @param digit digits after the decimal point. Left as-is when omitted.
363
+ *
364
+ * @example
365
+ * formatValue(1234, [['Hz', 1], ['kHz', 1000]], 2) // '1.23kHz'
366
+ * formatValue(1.5, 'Hz') // '1.5Hz'
367
+ */
368
+ declare function formatValue(value: number, units?: string | Units, digit?: number): string;
369
+ /**
370
+ * Read a value back out of text, undoing the scaling of {@link formatValue}.
371
+ *
372
+ * With a list of units the text has to be a number followed by an optional
373
+ * unit and nothing else, since the unit decides the scale; anything else reads
374
+ * as 0. With a single unit, or none, the first number found anywhere in the
375
+ * text is taken, so a half-typed entry still yields something.
376
+ *
377
+ * @example
378
+ * parseValue('1.23kHz', [['Hz', 1], ['kHz', 1000]]) // 1230
379
+ * parseValue('4abc') // 4
380
+ */
381
+ declare function parseValue(text: string, units?: string | Units): number;
71
382
  //#endregion
72
383
  //#region src/util.d.ts
73
384
  type Operator = '+' | '-' | '*' | '/';
@@ -77,5 +388,5 @@ declare function isEmpty(obj: object): boolean;
77
388
  declare function mod(n: number, m: number): number;
78
389
  declare function xor(a?: boolean, b?: boolean): boolean;
79
390
  //#endregion
80
- export { type InputEventOption, type NoteKey, type WhiteKey, clamp, dbToGain, decimalPart, degree, gainToDb, integerPart, isBlackKey, isEmpty, isWhiteKey, mapValue, mod, normalizeValue, noteKey, noteKeys, noteName, noteNumber, noteToFrequency, parseNoteName, radian, rawValue, skewWithCenterValue, stepValue, styleHelper, toFixed, whiteKeys, xor };
391
+ export { type InputEventOption, type NoteKey, type NoteRange, type PianoLayout, type Scale, type ScaleName, type Units, type ValueRange, type WhiteKey, applyDelta, blackKeyWidth, clamp, curveScale, curveWithCenterValue, dbToGain, decimalPart, degree, exponentialScale, formatValue, gainToDb, getNoteRangeArray, inScale, integerPart, isBlackKey, isEmpty, isWhiteKey, linearScale, mapValue, mod, normalizeValue, noteAt, noteKey, noteKeys, noteName, noteNumber, notePosition, noteToFrequency, parseNoteName, parseValue, pianoWidth, radian, rawValue, scaleIntervals, scaleNotes, selectUnit, skewScale, skewWithCenterValue, stepValue, styleHelper, symmetricSkewScale, toFixed, whiteKeys, xor };
81
392
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/math.ts","../src/midi.ts","../src/types.ts","../src/util.ts"],"mappings":";;AAGA;;iBAAgB,KAAA,CAAM,KAAA,UAAe,GAAA,UAAa,GAAA;;;;iBAOlC,cAAA,CACd,QAAA,UACA,GAAA,UACA,GAAA,UACA,IAAA;;;AAJF;iBAcgB,QAAA,CACd,eAAA,UACA,GAAA,UACA,GAAA,UACA,IAAA;AAAA,iBAUc,mBAAA,CACd,WAAA,UACA,GAAA,UACA,GAAA;AAAA,iBAOc,SAAA,CAAU,KAAA,UAAe,IAAA;AAAA,iBASzB,OAAA,CAAQ,CAAA,UAAW,cAAA;AAAA,iBAInB,WAAA,CAAY,CAAA;AAAA,iBAOZ,WAAA,CAAY,CAAA;AAAA,iBAIZ,MAAA,CAAO,MAAA;AAAA,iBAIP,MAAA,CAAO,MAAA;AAAA,iBAIP,QAAA,CACd,KAAA,UACA,KAAA,UACA,KAAA,UACA,MAAA,UACA,MAAA;AAAA,iBAKc,QAAA,CAAS,EAAA;AAAA,iBAIT,QAAA,CAAS,IAAA;;;cC5FZ,SAAA;AAAA,KAED,QAAA,WAAmB,SAAA;AAAA,cAElB,QAAA;AAAA,KAeD,OAAA,WAAkB,QAAA;AAAA,iBAEd,aAAA,CAAc,QAAA;UAKY,QAAA;;;;;ADlB1C;;iBC2BgB,UAAA,CAAW,QAAA;;;;;;;iBAaX,QAAA,CAAS,UAAA,cAAwB,OAAA;AD1BjD;;;AAAA,iBCmCgB,OAAA,CAAQ,UAAA,WAAqB,OAAA;;;;iBAO7B,UAAA,CAAW,IAAA;;;AD5B3B;iBC4CgB,UAAA,CAAW,IAAA;;;;;;;iBAUX,eAAA,CAAgB,IAAA,mBAAuB,MAAA,WAAY,EAAA;;;;ADzFnE;;KEAY,gBAAA;;;KCHP,QAAA;AAAA,iBAEW,WAAA,CAAY,KAAA;AAAA,iBACZ,WAAA,CACd,KAAA,mBACA,EAAA,EAAI,QAAA,EACJ,UAAA;AAAA,iBAyBc,OAAA,CAAQ,GAAA;AAAA,iBAIR,GAAA,CAAI,CAAA,UAAW,CAAA;AAAA,iBAIf,GAAA,CAAI,CAAA,YAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/math.ts","../src/types.ts","../src/scales.ts","../src/midi.ts","../src/piano.ts","../src/unit.ts","../src/util.ts"],"mappings":"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"}