lfocomp 0.1.0 → 0.1.1
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/CHANGELOG.md +20 -1
- package/README.md +2 -2
- package/lfo-ui.js +22 -12
- package/lfo.js +22 -12
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.1.1] - 2026-03-28
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
- LFO widget param sliders overflowing their containers (`min-width: 0` on grid cells)
|
|
12
|
+
- LFO widgets too narrow (~213 px) on typical viewports — panel moved above main grid, each widget now ~343 px
|
|
13
|
+
- `destroyLFO` now removes incoming LFO-chain routes as well as outgoing ones
|
|
14
|
+
- `ModIndicator._reposition` crash due to undefined `badge` variable
|
|
15
|
+
- Arc canvas height mismatch between construction and draw path
|
|
16
|
+
- `pointercancel` during drag left SVG wire overlay in the DOM
|
|
17
|
+
- Color-cycling underflow (`LFO_COLORS[-1] === undefined`) when label provided but color omitted on first `createLFO` call
|
|
18
|
+
- Stale `ModIndicator` badges persisting after routes deleted externally — `_pruneDeadRoutes()` runs each tick
|
|
19
|
+
- Escape key in click-to-type param editor no longer commits the value
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
- LFO widget params split into two visual groups: Rate/Depth (primary) and Phase/Offs./Jitter/Skew (secondary)
|
|
23
|
+
- 91-test suite across three files: `engine.test.js`, `widget.test.js`, `comp.test.js`
|
|
24
|
+
- Coverage thresholds in `vitest.config.js` (60 % lines/functions, 50 % branches)
|
|
25
|
+
|
|
8
26
|
## [0.1.0] - 2026-03-28
|
|
9
27
|
|
|
10
28
|
### Added
|
|
@@ -20,5 +38,6 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
20
38
|
- Log-scaled rate slider (0.01 Hz – 10 Hz)
|
|
21
39
|
- Zero runtime dependencies
|
|
22
40
|
|
|
23
|
-
[Unreleased]: https://github.com/KUSH42/lfocomp/compare/v0.1.
|
|
41
|
+
[Unreleased]: https://github.com/KUSH42/lfocomp/compare/v0.1.1...HEAD
|
|
42
|
+
[0.1.1]: https://github.com/KUSH42/lfocomp/compare/v0.1.0...v0.1.1
|
|
24
43
|
[0.1.0]: https://github.com/KUSH42/lfocomp/releases/tag/v0.1.0
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
[]()
|
|
9
9
|
[]()
|
|
10
|
-
[](https://www.npmjs.com/package/lfocomp)
|
|
11
11
|
|
|
12
12
|
**[Live demo](https://kush42.github.io/lfo.html)**
|
|
13
13
|
|
|
@@ -35,7 +35,7 @@ lfocomp is one import, three files, and you're live.
|
|
|
35
35
|
|
|
36
36
|
## Install
|
|
37
37
|
|
|
38
|
-
### npm
|
|
38
|
+
### npm
|
|
39
39
|
```bash
|
|
40
40
|
npm install lfocomp
|
|
41
41
|
```
|
package/lfo-ui.js
CHANGED
|
@@ -149,10 +149,17 @@ const CSS = `
|
|
|
149
149
|
gap: 5px;
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
+
.lfo-params-secondary {
|
|
153
|
+
border-top: 1px solid #2a2a3e;
|
|
154
|
+
padding-top: 5px;
|
|
155
|
+
margin-top: 4px;
|
|
156
|
+
}
|
|
157
|
+
|
|
152
158
|
.lfo-param-group {
|
|
153
159
|
display: flex;
|
|
154
160
|
flex-direction: column;
|
|
155
161
|
gap: 3px;
|
|
162
|
+
min-width: 0;
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
.lfo-param-group label {
|
|
@@ -770,18 +777,21 @@ export class LFOWidget {
|
|
|
770
777
|
canvasRow.appendChild(shapesEl);
|
|
771
778
|
root.appendChild(canvasRow);
|
|
772
779
|
|
|
773
|
-
// Param sliders —
|
|
774
|
-
const
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
this.
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
this.
|
|
782
|
-
this.
|
|
783
|
-
|
|
784
|
-
|
|
780
|
+
// Param sliders — two groups: primary (rate, depth) and secondary (phase, offset, jitter, skew)
|
|
781
|
+
const params1 = document.createElement('div');
|
|
782
|
+
params1.className = 'lfo-params';
|
|
783
|
+
this._rateInput = this._addParam(params1, 'Rate', 0.01, 10, 1, 0.01, 'baseRate', v => `${v.toFixed(2)}Hz`, 'log');
|
|
784
|
+
this._depthInput = this._addParam(params1, 'Depth', 0, 1, 1, 0.01, 'baseDepth', v => `${Math.round(v * 100)}%`);
|
|
785
|
+
|
|
786
|
+
const params2 = document.createElement('div');
|
|
787
|
+
params2.className = 'lfo-params lfo-params-secondary';
|
|
788
|
+
this._phaseInput = this._addParam(params2, 'Phase', 0, 1, 0, 0.01, 'phase', v => `${Math.round(v * 360)}°`);
|
|
789
|
+
this._offsetInput = this._addParam(params2, 'Offs.', -1, 1, 0, 0.01, 'offset', v => v.toFixed(2));
|
|
790
|
+
this._jitterInput = this._addParam(params2, 'Jitter', 0, 1, 0, 0.01, 'jitter', v => `${Math.round(v * 100)}%`);
|
|
791
|
+
this._skewInput = this._addParam(params2, 'Skew', 0, 1, 0.5, 0.01, 'skew', v => `${Math.round((v - 0.5) * 200)}%`);
|
|
792
|
+
|
|
793
|
+
root.appendChild(params1);
|
|
794
|
+
root.appendChild(params2);
|
|
785
795
|
|
|
786
796
|
// Connect handle
|
|
787
797
|
const handle = this._handle = document.createElement('div');
|
package/lfo.js
CHANGED
|
@@ -617,10 +617,17 @@ const CSS = `
|
|
|
617
617
|
gap: 5px;
|
|
618
618
|
}
|
|
619
619
|
|
|
620
|
+
.lfo-params-secondary {
|
|
621
|
+
border-top: 1px solid #2a2a3e;
|
|
622
|
+
padding-top: 5px;
|
|
623
|
+
margin-top: 4px;
|
|
624
|
+
}
|
|
625
|
+
|
|
620
626
|
.lfo-param-group {
|
|
621
627
|
display: flex;
|
|
622
628
|
flex-direction: column;
|
|
623
629
|
gap: 3px;
|
|
630
|
+
min-width: 0;
|
|
624
631
|
}
|
|
625
632
|
|
|
626
633
|
.lfo-param-group label {
|
|
@@ -1238,18 +1245,21 @@ class LFOWidget {
|
|
|
1238
1245
|
canvasRow.appendChild(shapesEl);
|
|
1239
1246
|
root.appendChild(canvasRow);
|
|
1240
1247
|
|
|
1241
|
-
// Param sliders —
|
|
1242
|
-
const
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
this.
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
this.
|
|
1250
|
-
this.
|
|
1251
|
-
|
|
1252
|
-
|
|
1248
|
+
// Param sliders — two groups: primary (rate, depth) and secondary (phase, offset, jitter, skew)
|
|
1249
|
+
const params1 = document.createElement('div');
|
|
1250
|
+
params1.className = 'lfo-params';
|
|
1251
|
+
this._rateInput = this._addParam(params1, 'Rate', 0.01, 10, 1, 0.01, 'baseRate', v => `${v.toFixed(2)}Hz`, 'log');
|
|
1252
|
+
this._depthInput = this._addParam(params1, 'Depth', 0, 1, 1, 0.01, 'baseDepth', v => `${Math.round(v * 100)}%`);
|
|
1253
|
+
|
|
1254
|
+
const params2 = document.createElement('div');
|
|
1255
|
+
params2.className = 'lfo-params lfo-params-secondary';
|
|
1256
|
+
this._phaseInput = this._addParam(params2, 'Phase', 0, 1, 0, 0.01, 'phase', v => `${Math.round(v * 360)}°`);
|
|
1257
|
+
this._offsetInput = this._addParam(params2, 'Offs.', -1, 1, 0, 0.01, 'offset', v => v.toFixed(2));
|
|
1258
|
+
this._jitterInput = this._addParam(params2, 'Jitter', 0, 1, 0, 0.01, 'jitter', v => `${Math.round(v * 100)}%`);
|
|
1259
|
+
this._skewInput = this._addParam(params2, 'Skew', 0, 1, 0.5, 0.01, 'skew', v => `${Math.round((v - 0.5) * 200)}%`);
|
|
1260
|
+
|
|
1261
|
+
root.appendChild(params1);
|
|
1262
|
+
root.appendChild(params2);
|
|
1253
1263
|
|
|
1254
1264
|
// Connect handle
|
|
1255
1265
|
const handle = this._handle = document.createElement('div');
|