@xsynaptic/sonic-ui 0.9.0 → 0.10.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/dist/default/elements/display-element.js +14 -2
- package/dist/default/elements/slider.js +1 -1
- package/dist/default/elements/spectrum.js +1 -0
- package/dist/default/elements/value-element.js +26 -3
- package/dist/default/elements/value-gestures.js +27 -15
- package/dist/default/elements/wave-element.js +5 -26
- package/dist/default/elements/waveform.js +1 -0
- package/dist/default/elements/wavestrip.js +0 -1
- package/dist/default/lib/fill-watch.js +29 -0
- package/dist/default/lib/hover-preview.js +12 -5
- package/dist/dev/elements/display-element.d.ts +4 -1
- package/dist/dev/elements/display-element.js +14 -2
- package/dist/dev/elements/display-element.js.map +1 -1
- package/dist/dev/elements/slider.js +1 -1
- package/dist/dev/elements/slider.js.map +1 -1
- package/dist/dev/elements/spectrum.d.ts +1 -0
- package/dist/dev/elements/spectrum.js +1 -0
- package/dist/dev/elements/spectrum.js.map +1 -1
- package/dist/dev/elements/value-element.d.ts +4 -1
- package/dist/dev/elements/value-element.js +28 -3
- package/dist/dev/elements/value-element.js.map +1 -1
- package/dist/dev/elements/value-gestures.js +27 -15
- package/dist/dev/elements/value-gestures.js.map +1 -1
- package/dist/dev/elements/wave-element.js +5 -26
- package/dist/dev/elements/wave-element.js.map +1 -1
- package/dist/dev/elements/waveform.js +1 -0
- package/dist/dev/elements/waveform.js.map +1 -1
- package/dist/dev/elements/wavestrip.js +0 -1
- package/dist/dev/elements/wavestrip.js.map +1 -1
- package/dist/dev/lib/fill-watch.js +30 -0
- package/dist/dev/lib/fill-watch.js.map +1 -0
- package/dist/dev/lib/hover-preview.js +12 -5
- package/dist/dev/lib/hover-preview.js.map +1 -1
- package/dist/styles/envelope.css +1 -1
- package/dist/styles/led.css +1 -1
- package/dist/styles/material.css +24 -8
- package/dist/styles/spectrum.css +5 -0
- package/dist/styles/switch.css +42 -33
- package/dist/styles/waveform.css +21 -2
- package/dist/styles/wavestrip.css +9 -6
- package/dist/styles/xy.css +4 -4
- package/package.json +1 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { SonicElement } from "./sonic-element.js";
|
|
2
2
|
import { bindSurface } from "../lib/canvas-surface.js";
|
|
3
|
+
import { bindFill } from "../lib/fill-watch.js";
|
|
3
4
|
|
|
4
5
|
//#region src/elements/display-element.ts
|
|
5
6
|
var SonicDisplayElement = class extends SonicElement {
|
|
6
7
|
static observedAttributes = [
|
|
7
8
|
...SonicElement.observedAttributes,
|
|
9
|
+
"fill",
|
|
8
10
|
"max",
|
|
9
11
|
"min"
|
|
10
12
|
];
|
|
@@ -15,6 +17,12 @@ var SonicDisplayElement = class extends SonicElement {
|
|
|
15
17
|
this.#analyser = node ?? void 0;
|
|
16
18
|
this.#surface?.requestFrame();
|
|
17
19
|
}
|
|
20
|
+
get fill() {
|
|
21
|
+
return this.hasAttribute("fill");
|
|
22
|
+
}
|
|
23
|
+
set fill(isFilling) {
|
|
24
|
+
this.reflect("fill", isFilling);
|
|
25
|
+
}
|
|
18
26
|
get max() {
|
|
19
27
|
return this.numberAttribute("max", 0);
|
|
20
28
|
}
|
|
@@ -30,11 +38,13 @@ var SonicDisplayElement = class extends SonicElement {
|
|
|
30
38
|
#analyser;
|
|
31
39
|
#buffer = /* @__PURE__ */ new Float32Array(0);
|
|
32
40
|
#surface;
|
|
33
|
-
|
|
41
|
+
#syncFill;
|
|
42
|
+
attributeChangedCallback(name) {
|
|
43
|
+
if (name === "fill") this.#syncFill?.(this.fill);
|
|
34
44
|
this.#surface?.invalidate();
|
|
35
45
|
}
|
|
36
46
|
connectedCallback() {
|
|
37
|
-
this.upgradeProperties("analyser", "max", "min");
|
|
47
|
+
this.upgradeProperties("analyser", "fill", "max", "min");
|
|
38
48
|
super.connectedCallback();
|
|
39
49
|
}
|
|
40
50
|
push(frame) {
|
|
@@ -57,6 +67,8 @@ var SonicDisplayElement = class extends SonicElement {
|
|
|
57
67
|
signal
|
|
58
68
|
});
|
|
59
69
|
this.checkStyles(control, this.sheet);
|
|
70
|
+
this.#syncFill = bindFill(control, this.sizeProperty, signal);
|
|
71
|
+
this.#syncFill(this.fill);
|
|
60
72
|
}
|
|
61
73
|
surface() {
|
|
62
74
|
return this.#surface;
|
|
@@ -102,7 +102,7 @@ var SonicSlider = class extends SonicValueElement {
|
|
|
102
102
|
if (event.propertyName === "--_sonic-slider-value") this.toggleState("springing", false);
|
|
103
103
|
}, { signal });
|
|
104
104
|
this.bindHover(slider, signal, {
|
|
105
|
-
canShow: () => this.scrub && this.
|
|
105
|
+
canShow: () => this.scrub && this.orientation === "horizontal",
|
|
106
106
|
place: () => {
|
|
107
107
|
this.#placeReadout(slider);
|
|
108
108
|
},
|
|
@@ -97,6 +97,12 @@ var SonicValueElement = class extends SonicFormElement {
|
|
|
97
97
|
set doublePress(gesture) {
|
|
98
98
|
this.reflect("double-press", gesture);
|
|
99
99
|
}
|
|
100
|
+
get formatEntry() {
|
|
101
|
+
return this.#formatEntry;
|
|
102
|
+
}
|
|
103
|
+
set formatEntry(format) {
|
|
104
|
+
this.#formatEntry = format;
|
|
105
|
+
}
|
|
100
106
|
get formatSpokenValue() {
|
|
101
107
|
return this.#formatSpokenValue;
|
|
102
108
|
}
|
|
@@ -111,6 +117,9 @@ var SonicValueElement = class extends SonicFormElement {
|
|
|
111
117
|
this.#formatValue = format;
|
|
112
118
|
this.render();
|
|
113
119
|
}
|
|
120
|
+
get hoverValue() {
|
|
121
|
+
return this.#hover?.value();
|
|
122
|
+
}
|
|
114
123
|
get keyStep() {
|
|
115
124
|
return this.optionalNumberAttribute("key-step");
|
|
116
125
|
}
|
|
@@ -208,6 +217,7 @@ var SonicValueElement = class extends SonicFormElement {
|
|
|
208
217
|
asked: void 0,
|
|
209
218
|
value: 0
|
|
210
219
|
};
|
|
220
|
+
#formatEntry;
|
|
211
221
|
#formatSpokenValue;
|
|
212
222
|
#formatValue;
|
|
213
223
|
#gestures;
|
|
@@ -237,7 +247,7 @@ var SonicValueElement = class extends SonicFormElement {
|
|
|
237
247
|
this.render();
|
|
238
248
|
}
|
|
239
249
|
connectedCallback() {
|
|
240
|
-
this.upgradeProperties("default", "dimmed", "doublePress", "max", "midpoint", "min", "notched", "origin", "readout", "spokenStep", "step", "taper", "positions", "detent", "formatValue", "formatSpokenValue", "keyStep", "parseValue", "value");
|
|
250
|
+
this.upgradeProperties("default", "dimmed", "doublePress", "max", "midpoint", "min", "notched", "origin", "readout", "spokenStep", "step", "taper", "positions", "detent", "formatEntry", "formatValue", "formatSpokenValue", "keyStep", "parseValue", "value");
|
|
241
251
|
super.connectedCallback();
|
|
242
252
|
}
|
|
243
253
|
bindGestures(control, signal, grab) {
|
|
@@ -254,7 +264,7 @@ var SonicValueElement = class extends SonicFormElement {
|
|
|
254
264
|
},
|
|
255
265
|
doublePress: () => this.doublePress,
|
|
256
266
|
entryId: `sonic-entry-${this.#instance}`,
|
|
257
|
-
entryText: () => this.#
|
|
267
|
+
entryText: () => this.#entryText(),
|
|
258
268
|
forwardNaming: (target, isNamed) => {
|
|
259
269
|
this.forwardNaming(target, isNamed);
|
|
260
270
|
},
|
|
@@ -280,15 +290,22 @@ var SonicValueElement = class extends SonicFormElement {
|
|
|
280
290
|
value: () => this.#cell.value
|
|
281
291
|
}, control);
|
|
282
292
|
this.#gestures.bind(signal, grab);
|
|
293
|
+
control.addEventListener("pointerup", (event) => {
|
|
294
|
+
this.#hover?.at(event);
|
|
295
|
+
}, { signal });
|
|
283
296
|
}
|
|
284
|
-
bindHover(control, signal, { canShow, place, valueAt }) {
|
|
297
|
+
bindHover(control, signal, { canShow = () => true, place, valueAt }) {
|
|
285
298
|
this.#hover = bindHoverPreview(control, {
|
|
286
299
|
canShow,
|
|
300
|
+
changed: () => {
|
|
301
|
+
this.dispatchEvent(new Event("sonic-hover", { bubbles: true }));
|
|
302
|
+
},
|
|
287
303
|
dismiss: () => {
|
|
288
304
|
this.render();
|
|
289
305
|
},
|
|
290
306
|
isTaken: () => this.#isEditing() || this.isRevealed(),
|
|
291
307
|
show: () => {
|
|
308
|
+
if (!this.readout) return;
|
|
292
309
|
this.renderReadout();
|
|
293
310
|
place();
|
|
294
311
|
},
|
|
@@ -376,6 +393,12 @@ var SonicValueElement = class extends SonicFormElement {
|
|
|
376
393
|
travelPx(control, property) {
|
|
377
394
|
return Math.max(1, readPxProperty(getComputedStyle(control), property, fallbackTravelPx));
|
|
378
395
|
}
|
|
396
|
+
#entryText() {
|
|
397
|
+
const value = this.#cell.value;
|
|
398
|
+
if (this.#formatEntry) return this.#formatEntry(value);
|
|
399
|
+
if (!this.#parseValue) return String(value);
|
|
400
|
+
return this.valueText;
|
|
401
|
+
}
|
|
379
402
|
#isEditing() {
|
|
380
403
|
return this.#gestures?.isEditing() === true;
|
|
381
404
|
}
|
|
@@ -14,6 +14,7 @@ const detentZonePx = 8;
|
|
|
14
14
|
var ValueGestures = class {
|
|
15
15
|
#claim = new ReadoutClaim(() => {
|
|
16
16
|
this.#host.holdChanged();
|
|
17
|
+
this.#showRevealed();
|
|
17
18
|
});
|
|
18
19
|
#control;
|
|
19
20
|
#entry;
|
|
@@ -43,8 +44,12 @@ var ValueGestures = class {
|
|
|
43
44
|
return;
|
|
44
45
|
}
|
|
45
46
|
const fromValue = host.value();
|
|
47
|
+
host.toggleState("dragging", true);
|
|
46
48
|
const axis = grab(event);
|
|
47
|
-
if (!axis)
|
|
49
|
+
if (!axis) {
|
|
50
|
+
host.toggleState("dragging", false);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
48
53
|
const drag = {
|
|
49
54
|
...axis,
|
|
50
55
|
fromValue,
|
|
@@ -145,8 +150,9 @@ var ValueGestures = class {
|
|
|
145
150
|
const next = this.#keyTarget(event.key);
|
|
146
151
|
if (next === void 0) return;
|
|
147
152
|
event.preventDefault();
|
|
148
|
-
this.#keyTo(event, next);
|
|
149
153
|
this.#claim.reveal("keys");
|
|
154
|
+
this.#showRevealed();
|
|
155
|
+
this.#keyTo(event, next);
|
|
150
156
|
host.holdChanged();
|
|
151
157
|
}, { signal });
|
|
152
158
|
control.addEventListener("keyup", (event) => {
|
|
@@ -167,7 +173,18 @@ var ValueGestures = class {
|
|
|
167
173
|
if (host.input(landed)) host.dispatch("change");
|
|
168
174
|
}
|
|
169
175
|
#concealKeyReveal() {
|
|
170
|
-
if (this.#claim.conceal("keys"))
|
|
176
|
+
if (!this.#claim.conceal("keys")) return;
|
|
177
|
+
this.#host.holdChanged();
|
|
178
|
+
this.#showRevealed();
|
|
179
|
+
}
|
|
180
|
+
#crossCancelZone(drag, value) {
|
|
181
|
+
const host = this.#host;
|
|
182
|
+
const isOutside = !drag.isOutside;
|
|
183
|
+
drag.isOutside = isOutside;
|
|
184
|
+
host.toggleState("cancelling", isOutside);
|
|
185
|
+
if (isOutside) this.#renderDragReveal(drag);
|
|
186
|
+
host.input(isOutside ? drag.fromValue : value);
|
|
187
|
+
if (!isOutside) this.#renderDragReveal(drag);
|
|
171
188
|
}
|
|
172
189
|
#dragging() {
|
|
173
190
|
return this.#pointerDrag?.current();
|
|
@@ -185,13 +202,8 @@ var ValueGestures = class {
|
|
|
185
202
|
drag.state = this.#withinLimit(mapping, state);
|
|
186
203
|
if (value === void 0) return;
|
|
187
204
|
if (!wasEngaged) this.#reveal(drag);
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
drag.isOutside = isOutside;
|
|
191
|
-
host.toggleState("cancelling", isOutside);
|
|
192
|
-
}
|
|
193
|
-
host.input(isOutside ? drag.fromValue : value);
|
|
194
|
-
if (isCrossing) this.#renderDragReveal(drag);
|
|
205
|
+
if (isOutside === drag.isOutside) host.input(value);
|
|
206
|
+
else this.#crossCancelZone(drag, value);
|
|
195
207
|
}
|
|
196
208
|
#endKeyScrub() {
|
|
197
209
|
const host = this.#host;
|
|
@@ -221,16 +233,15 @@ var ValueGestures = class {
|
|
|
221
233
|
this.#claim.conceal("drag");
|
|
222
234
|
host.toggleState("cancelling", false);
|
|
223
235
|
host.holdChanged();
|
|
224
|
-
this.#showRevealed(
|
|
236
|
+
this.#showRevealed();
|
|
225
237
|
if (host.value() !== drag.fromValue) host.dispatch("change");
|
|
226
238
|
this.#springBack();
|
|
227
239
|
}
|
|
228
240
|
#renderDragReveal(drag) {
|
|
229
|
-
|
|
230
|
-
if (isRevealed) this.#claim.reveal("drag");
|
|
241
|
+
if (drag.isRevealed && !drag.isOutside) this.#claim.reveal("drag");
|
|
231
242
|
else this.#claim.conceal("drag");
|
|
232
243
|
this.#host.holdChanged();
|
|
233
|
-
this.#showRevealed(
|
|
244
|
+
this.#showRevealed();
|
|
234
245
|
}
|
|
235
246
|
#reset() {
|
|
236
247
|
this.#commit(this.#host.default() ?? NaN);
|
|
@@ -251,7 +262,8 @@ var ValueGestures = class {
|
|
|
251
262
|
}
|
|
252
263
|
host.input(next);
|
|
253
264
|
}
|
|
254
|
-
#showRevealed(
|
|
265
|
+
#showRevealed() {
|
|
266
|
+
const { isRevealed } = this.#claim;
|
|
255
267
|
if (isRevealed === this.#isRevealed) return;
|
|
256
268
|
this.#isRevealed = isRevealed;
|
|
257
269
|
this.#host.toggleState("revealed", isRevealed);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SonicValueElement } from "./value-element.js";
|
|
2
2
|
import { bindSurface } from "../lib/canvas-surface.js";
|
|
3
|
+
import { bindFill } from "../lib/fill-watch.js";
|
|
3
4
|
|
|
4
5
|
//#region src/elements/wave-element.ts
|
|
5
6
|
function markerKey(marker) {
|
|
@@ -31,12 +32,12 @@ var SonicWaveElement = class extends SonicValueElement {
|
|
|
31
32
|
this.render();
|
|
32
33
|
}
|
|
33
34
|
#current;
|
|
34
|
-
#fillWatch;
|
|
35
35
|
#markers = [];
|
|
36
36
|
#surface;
|
|
37
|
+
#syncFill;
|
|
37
38
|
attributeChangedCallback(name) {
|
|
38
39
|
super.attributeChangedCallback(name);
|
|
39
|
-
if (name === "fill") this.#
|
|
40
|
+
if (name === "fill") this.#syncFill?.(this.fill);
|
|
40
41
|
}
|
|
41
42
|
connectedCallback() {
|
|
42
43
|
this.upgradeProperties("fill", "markers");
|
|
@@ -63,11 +64,8 @@ var SonicWaveElement = class extends SonicValueElement {
|
|
|
63
64
|
});
|
|
64
65
|
this.render();
|
|
65
66
|
this.checkStyles(control, this.sheet);
|
|
66
|
-
this.#
|
|
67
|
-
|
|
68
|
-
this.#fillWatch?.disconnect();
|
|
69
|
-
this.#fillWatch = void 0;
|
|
70
|
-
}, { once: true });
|
|
67
|
+
this.#syncFill = bindFill(control, this.sizeProperty, signal);
|
|
68
|
+
this.#syncFill(this.fill);
|
|
71
69
|
}
|
|
72
70
|
focusTarget() {
|
|
73
71
|
return this.control;
|
|
@@ -105,25 +103,6 @@ var SonicWaveElement = class extends SonicValueElement {
|
|
|
105
103
|
surface() {
|
|
106
104
|
return this.#surface;
|
|
107
105
|
}
|
|
108
|
-
#watchFill() {
|
|
109
|
-
const control = this.control;
|
|
110
|
-
const isFilling = this.fill && this.isBound();
|
|
111
|
-
if (isFilling === (this.#fillWatch !== void 0)) return;
|
|
112
|
-
this.#fillWatch?.disconnect();
|
|
113
|
-
this.#fillWatch = void 0;
|
|
114
|
-
if (!isFilling) {
|
|
115
|
-
control.style.removeProperty(this.sizeProperty);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
this.#fillWatch = new ResizeObserver((entries) => {
|
|
119
|
-
const box = entries.at(-1)?.borderBoxSize[0];
|
|
120
|
-
if (!box) return;
|
|
121
|
-
requestAnimationFrame(() => {
|
|
122
|
-
if (this.#fillWatch) control.style.setProperty(this.sizeProperty, `${String(box.blockSize)}px`);
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
this.#fillWatch.observe(control);
|
|
126
|
-
}
|
|
127
106
|
};
|
|
128
107
|
|
|
129
108
|
//#endregion
|
|
@@ -25,6 +25,7 @@ const placeholderAmplitude = .2;
|
|
|
25
25
|
const renderWaveform = template(`
|
|
26
26
|
<div class="sonic-waveform" role="slider" tabindex="0">
|
|
27
27
|
<canvas class="sonic-waveform-canvas" aria-hidden="true"></canvas>
|
|
28
|
+
<div class="sonic-waveform-scrim" aria-hidden="true"></div>
|
|
28
29
|
<div class="sonic-waveform-ghost" aria-hidden="true" hidden></div>
|
|
29
30
|
<div class="sonic-waveform-playhead" aria-hidden="true"></div>
|
|
30
31
|
<div class="sonic-waveform-label" aria-hidden="true" hidden></div>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region src/lib/fill-watch.ts
|
|
2
|
+
function bindFill(control, sizeProperty, signal) {
|
|
3
|
+
let watch;
|
|
4
|
+
const stop = () => {
|
|
5
|
+
watch?.disconnect();
|
|
6
|
+
watch = void 0;
|
|
7
|
+
};
|
|
8
|
+
signal.addEventListener("abort", stop, { once: true });
|
|
9
|
+
return (isFilling) => {
|
|
10
|
+
if (signal.aborted || isFilling === (watch !== void 0)) return;
|
|
11
|
+
stop();
|
|
12
|
+
if (!isFilling) {
|
|
13
|
+
control.style.removeProperty(sizeProperty);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const started = new ResizeObserver((entries) => {
|
|
17
|
+
const box = entries.at(-1)?.borderBoxSize[0];
|
|
18
|
+
if (!box) return;
|
|
19
|
+
requestAnimationFrame(() => {
|
|
20
|
+
if (watch === started) control.style.setProperty(sizeProperty, `${String(box.blockSize)}px`);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
watch = started;
|
|
24
|
+
started.observe(control);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//#endregion
|
|
29
|
+
export { bindFill };
|
|
@@ -3,6 +3,11 @@ function bindHoverPreview(target, options, signal) {
|
|
|
3
3
|
let hover;
|
|
4
4
|
let isDismissed = false;
|
|
5
5
|
let escapeWatch;
|
|
6
|
+
const hold = (value) => {
|
|
7
|
+
if (value === hover) return;
|
|
8
|
+
hover = value;
|
|
9
|
+
options.changed();
|
|
10
|
+
};
|
|
6
11
|
const watchEscape = (isHovered) => {
|
|
7
12
|
if (!isHovered) {
|
|
8
13
|
escapeWatch?.abort();
|
|
@@ -13,21 +18,22 @@ function bindHoverPreview(target, options, signal) {
|
|
|
13
18
|
escapeWatch = new AbortController();
|
|
14
19
|
target.ownerDocument.addEventListener("keydown", (event) => {
|
|
15
20
|
if (hover === void 0 || event.key !== "Escape") return;
|
|
16
|
-
hover = void 0;
|
|
17
21
|
isDismissed = true;
|
|
22
|
+
hold(void 0);
|
|
18
23
|
options.dismiss();
|
|
19
24
|
}, { signal: escapeWatch.signal });
|
|
20
25
|
};
|
|
21
26
|
const hoverAt = (value) => {
|
|
22
27
|
if (value === void 0) isDismissed = false;
|
|
23
|
-
if (!isDismissed && !options.isTaken())
|
|
28
|
+
if (!isDismissed && !options.isTaken()) hold(value);
|
|
24
29
|
options.show();
|
|
25
30
|
watchEscape(value !== void 0);
|
|
26
31
|
};
|
|
27
|
-
|
|
32
|
+
const at = (event) => {
|
|
28
33
|
if (event.pointerType === "touch" || event.buttons !== 0 || !options.canShow()) return;
|
|
29
34
|
hoverAt(options.valueAt(event));
|
|
30
|
-
}
|
|
35
|
+
};
|
|
36
|
+
target.addEventListener("pointermove", at, { signal });
|
|
31
37
|
for (const type of ["pointerdown", "pointerleave"]) target.addEventListener(type, () => {
|
|
32
38
|
hoverAt(void 0);
|
|
33
39
|
}, { signal });
|
|
@@ -35,8 +41,9 @@ function bindHoverPreview(target, options, signal) {
|
|
|
35
41
|
watchEscape(false);
|
|
36
42
|
}, { once: true });
|
|
37
43
|
return {
|
|
44
|
+
at,
|
|
38
45
|
clear: () => {
|
|
39
|
-
|
|
46
|
+
hold(void 0);
|
|
40
47
|
},
|
|
41
48
|
value: () => hover
|
|
42
49
|
};
|
|
@@ -6,6 +6,8 @@ export declare abstract class SonicDisplayElement<Colour extends string, Numeric
|
|
|
6
6
|
static readonly observedAttributes: string[];
|
|
7
7
|
get analyser(): AnalyserNode | undefined;
|
|
8
8
|
set analyser(node: AnalyserNode | null | undefined);
|
|
9
|
+
get fill(): boolean;
|
|
10
|
+
set fill(isFilling: boolean);
|
|
9
11
|
get max(): number;
|
|
10
12
|
set max(decibels: number | undefined);
|
|
11
13
|
get min(): number;
|
|
@@ -15,7 +17,8 @@ export declare abstract class SonicDisplayElement<Colour extends string, Numeric
|
|
|
15
17
|
protected abstract readonly control: HTMLElement;
|
|
16
18
|
protected abstract readonly numbers: Record<Numeric, `--_sonic-${string}`>;
|
|
17
19
|
protected abstract readonly sheet: string;
|
|
18
|
-
|
|
20
|
+
protected abstract readonly sizeProperty: `--_sonic-${string}`;
|
|
21
|
+
attributeChangedCallback(name: string): void;
|
|
19
22
|
connectedCallback(): void;
|
|
20
23
|
push(frame: Float32Array): void;
|
|
21
24
|
repaint(): void;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { SonicElement } from "./sonic-element.js";
|
|
2
2
|
import { bindSurface } from "../lib/canvas-surface.js";
|
|
3
|
+
import { bindFill } from "../lib/fill-watch.js";
|
|
3
4
|
|
|
4
5
|
//#region src/elements/display-element.ts
|
|
5
6
|
var SonicDisplayElement = class extends SonicElement {
|
|
6
7
|
static observedAttributes = [
|
|
7
8
|
...SonicElement.observedAttributes,
|
|
9
|
+
"fill",
|
|
8
10
|
"max",
|
|
9
11
|
"min"
|
|
10
12
|
];
|
|
@@ -15,6 +17,12 @@ var SonicDisplayElement = class extends SonicElement {
|
|
|
15
17
|
this.#analyser = node ?? void 0;
|
|
16
18
|
this.#surface?.requestFrame();
|
|
17
19
|
}
|
|
20
|
+
get fill() {
|
|
21
|
+
return this.hasAttribute("fill");
|
|
22
|
+
}
|
|
23
|
+
set fill(isFilling) {
|
|
24
|
+
this.reflect("fill", isFilling);
|
|
25
|
+
}
|
|
18
26
|
get max() {
|
|
19
27
|
return this.numberAttribute("max", 0);
|
|
20
28
|
}
|
|
@@ -30,11 +38,13 @@ var SonicDisplayElement = class extends SonicElement {
|
|
|
30
38
|
#analyser;
|
|
31
39
|
#buffer = /* @__PURE__ */ new Float32Array(0);
|
|
32
40
|
#surface;
|
|
33
|
-
|
|
41
|
+
#syncFill;
|
|
42
|
+
attributeChangedCallback(name) {
|
|
43
|
+
if (name === "fill") this.#syncFill?.(this.fill);
|
|
34
44
|
this.#surface?.invalidate();
|
|
35
45
|
}
|
|
36
46
|
connectedCallback() {
|
|
37
|
-
this.upgradeProperties("analyser", "max", "min");
|
|
47
|
+
this.upgradeProperties("analyser", "fill", "max", "min");
|
|
38
48
|
super.connectedCallback();
|
|
39
49
|
}
|
|
40
50
|
push(frame) {
|
|
@@ -57,6 +67,8 @@ var SonicDisplayElement = class extends SonicElement {
|
|
|
57
67
|
signal
|
|
58
68
|
});
|
|
59
69
|
this.checkStyles(control, this.sheet);
|
|
70
|
+
this.#syncFill = bindFill(control, this.sizeProperty, signal);
|
|
71
|
+
this.#syncFill(this.fill);
|
|
60
72
|
}
|
|
61
73
|
surface() {
|
|
62
74
|
return this.#surface;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-element.js","names":[],"sources":["../../../src/elements/display-element.ts"],"sourcesContent":["import type { Surface, SurfaceFrame } from '#lib/canvas-surface.ts';\n\nimport { SonicElement } from '#elements/sonic-element.ts';\nimport { bindSurface } from '#lib/canvas-surface.ts';\n\nexport abstract class SonicDisplayElement<\n\tColour extends string,\n\tNumeric extends string = never,\n> extends SonicElement {\n\tstatic override readonly observedAttributes = [...SonicElement.observedAttributes
|
|
1
|
+
{"version":3,"file":"display-element.js","names":[],"sources":["../../../src/elements/display-element.ts"],"sourcesContent":["import type { Surface, SurfaceFrame } from '#lib/canvas-surface.ts';\n\nimport { SonicElement } from '#elements/sonic-element.ts';\nimport { bindSurface } from '#lib/canvas-surface.ts';\nimport { bindFill } from '#lib/fill-watch.ts';\n\nexport abstract class SonicDisplayElement<\n\tColour extends string,\n\tNumeric extends string = never,\n> extends SonicElement {\n\tstatic override readonly observedAttributes = [\n\t\t...SonicElement.observedAttributes,\n\t\t'fill',\n\t\t'max',\n\t\t'min',\n\t];\n\n\tget analyser(): AnalyserNode | undefined {\n\t\treturn this.#analyser;\n\t}\n\n\tset analyser(node: AnalyserNode | null | undefined) {\n\t\tthis.#analyser = node ?? undefined;\n\t\tthis.#surface?.requestFrame();\n\t}\n\n\t// fallow-ignore-next-line code-duplication -- one accessor pair per reflected attribute\n\tget fill(): boolean {\n\t\treturn this.hasAttribute('fill');\n\t}\n\n\tset fill(isFilling: boolean) {\n\t\tthis.reflect('fill', isFilling);\n\t}\n\n\t// fallow-ignore-next-line code-duplication -- one accessor pair per reflected attribute\n\tget max(): number {\n\t\treturn this.numberAttribute('max', 0);\n\t}\n\n\tset max(decibels: number | undefined) {\n\t\tthis.reflect('max', decibels);\n\t}\n\n\tget min(): number {\n\t\treturn this.numberAttribute('min', -90);\n\t}\n\n\tset min(decibels: number | undefined) {\n\t\tthis.reflect('min', decibels);\n\t}\n\n\tprotected abstract readonly canvas: HTMLCanvasElement;\n\n\tprotected abstract readonly colours: Record<Colour, `--_sonic-${string}`>;\n\n\tprotected abstract readonly control: HTMLElement;\n\n\tprotected abstract readonly numbers: Record<Numeric, `--_sonic-${string}`>;\n\n\tprotected abstract readonly sheet: string;\n\n\tprotected abstract readonly sizeProperty: `--_sonic-${string}`;\n\n\t#analyser: AnalyserNode | undefined;\n\n\t#buffer = new Float32Array(0);\n\n\t#surface: Surface | undefined;\n\n\t#syncFill: ((isFilling: boolean) => void) | undefined;\n\n\tattributeChangedCallback(name: string): void {\n\t\tif (name === 'fill') this.#syncFill?.(this.fill);\n\t\tthis.#surface?.invalidate();\n\t}\n\n\toverride connectedCallback(): void {\n\t\tthis.upgradeProperties('analyser', 'fill', 'max', 'min');\n\t\tsuper.connectedCallback();\n\t}\n\n\tpush(frame: Float32Array): void {\n\t\tthis.receive(frame);\n\t\tthis.#surface?.requestFrame();\n\t}\n\n\t// fallow-ignore-next-line code-duplication -- the wave controls keep their own copy of the surface binding\n\trepaint(): void {\n\t\tthis.#surface?.rebuild();\n\t}\n\n\tprotected connect(signal: AbortSignal): void {\n\t\tconst control = this.control;\n\n\t\tthis.keepControl(control, signal);\n\t\tthis.#surface = bindSurface({\n\t\t\tcanvas: this.canvas,\n\t\t\tcolours: this.colours,\n\t\t\tnumbers: this.numbers,\n\t\t\tpaint: (context, frame) => {\n\t\t\t\tthis.#paint(context, frame);\n\t\t\t},\n\t\t\tsignal,\n\t\t});\n\t\tthis.checkStyles(control, this.sheet);\n\t\tthis.#syncFill = bindFill(control, this.sizeProperty, signal);\n\t\tthis.#syncFill(this.fill);\n\t}\n\n\tprotected abstract paint(\n\t\tcontext: CanvasRenderingContext2D,\n\t\tframe: SurfaceFrame<Colour, never, Numeric>,\n\t): void;\n\n\tprotected abstract pull(analyser: AnalyserNode, buffer: Float32Array<ArrayBuffer>): void;\n\n\tprotected abstract receive(frame: Float32Array): void;\n\n\tprotected surface(): Surface | undefined {\n\t\treturn this.#surface;\n\t}\n\n\t// The node never signals that sound came back, so every paint pulls\n\t#paint(context: CanvasRenderingContext2D, frame: SurfaceFrame<Colour, never, Numeric>): void {\n\t\tconst analyser = this.isDisabled() ? undefined : this.#analyser;\n\n\t\tif (analyser) {\n\t\t\tif (this.#buffer.length !== analyser.frequencyBinCount) {\n\t\t\t\tthis.#buffer = new Float32Array(analyser.frequencyBinCount);\n\t\t\t}\n\t\t\tthis.pull(analyser, this.#buffer);\n\t\t\tthis.receive(this.#buffer);\n\t\t}\n\t\tthis.paint(context, frame);\n\t\tif (analyser) this.#surface?.requestFrame();\n\t}\n}\n"],"mappings":";;;;;AAMA,IAAsB,sBAAtB,cAGU,aAAa;CACtB,OAAyB,qBAAqB;EAC7C,GAAG,aAAa;EAChB;EACA;EACA;CACD;CAEA,IAAI,WAAqC;EACxC,OAAO,KAAK;CACb;CAEA,IAAI,SAAS,MAAuC;EACnD,KAAK,YAAY,QAAQ;EACzB,KAAK,UAAU,aAAa;CAC7B;CAGA,IAAI,OAAgB;EACnB,OAAO,KAAK,aAAa,MAAM;CAChC;CAEA,IAAI,KAAK,WAAoB;EAC5B,KAAK,QAAQ,QAAQ,SAAS;CAC/B;CAGA,IAAI,MAAc;EACjB,OAAO,KAAK,gBAAgB,OAAO,CAAC;CACrC;CAEA,IAAI,IAAI,UAA8B;EACrC,KAAK,QAAQ,OAAO,QAAQ;CAC7B;CAEA,IAAI,MAAc;EACjB,OAAO,KAAK,gBAAgB,OAAO,GAAG;CACvC;CAEA,IAAI,IAAI,UAA8B;EACrC,KAAK,QAAQ,OAAO,QAAQ;CAC7B;CAcA;CAEA,0BAAU,IAAI,aAAa,CAAC;CAE5B;CAEA;CAEA,yBAAyB,MAAoB;EAC5C,IAAI,SAAS,QAAQ,KAAK,YAAY,KAAK,IAAI;EAC/C,KAAK,UAAU,WAAW;CAC3B;CAEA,AAAS,oBAA0B;EAClC,KAAK,kBAAkB,YAAY,QAAQ,OAAO,KAAK;EACvD,MAAM,kBAAkB;CACzB;CAEA,KAAK,OAA2B;EAC/B,KAAK,QAAQ,KAAK;EAClB,KAAK,UAAU,aAAa;CAC7B;CAGA,UAAgB;EACf,KAAK,UAAU,QAAQ;CACxB;CAEA,AAAU,QAAQ,QAA2B;EAC5C,MAAM,UAAU,KAAK;EAErB,KAAK,YAAY,SAAS,MAAM;EAChC,KAAK,WAAW,YAAY;GAC3B,QAAQ,KAAK;GACb,SAAS,KAAK;GACd,SAAS,KAAK;GACd,QAAQ,SAAS,UAAU;IAC1B,KAAK,OAAO,SAAS,KAAK;GAC3B;GACA;EACD,CAAC;EACD,KAAK,YAAY,SAAS,KAAK,KAAK;EACpC,KAAK,YAAY,SAAS,SAAS,KAAK,cAAc,MAAM;EAC5D,KAAK,UAAU,KAAK,IAAI;CACzB;CAWA,AAAU,UAA+B;EACxC,OAAO,KAAK;CACb;CAGA,OAAO,SAAmC,OAAmD;EAC5F,MAAM,WAAW,KAAK,WAAW,IAAI,SAAY,KAAK;EAEtD,IAAI,UAAU;GACb,IAAI,KAAK,QAAQ,WAAW,SAAS,mBACpC,KAAK,UAAU,IAAI,aAAa,SAAS,iBAAiB;GAE3D,KAAK,KAAK,UAAU,KAAK,OAAO;GAChC,KAAK,QAAQ,KAAK,OAAO;EAC1B;EACA,KAAK,MAAM,SAAS,KAAK;EACzB,IAAI,UAAU,KAAK,UAAU,aAAa;CAC3C;AACD"}
|
|
@@ -102,7 +102,7 @@ var SonicSlider = class extends SonicValueElement {
|
|
|
102
102
|
if (event.propertyName === "--_sonic-slider-value") this.toggleState("springing", false);
|
|
103
103
|
}, { signal });
|
|
104
104
|
this.bindHover(slider, signal, {
|
|
105
|
-
canShow: () => this.scrub && this.
|
|
105
|
+
canShow: () => this.scrub && this.orientation === "horizontal",
|
|
106
106
|
place: () => {
|
|
107
107
|
this.#placeReadout(slider);
|
|
108
108
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slider.js","names":[],"sources":["../../../src/elements/slider.ts"],"sourcesContent":["import type { ValueAxis } from '#elements/value-gestures.ts';\nimport type { TimeRegions } from '#lib/time-regions.ts';\n\nimport { createModulation } from '#elements/modulation.ts';\nimport { bindScale } from '#elements/scale.ts';\nimport { SonicValueElement } from '#elements/value-element.ts';\nimport { clampProportion } from '#lib/math.ts';\nimport { requireChild, template } from '#lib/render.ts';\nimport { sortedRegions } from '#lib/time-regions.ts';\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'sonic-slider': SonicSlider;\n\t}\n}\n\ninterface SliderAxis extends ValueAxis {\n\tstartPx: number;\n}\n\nfunction grooveStop(proportion: number): string {\n\tif (proportion <= 0) return '0%';\n\tif (proportion >= 1) return '100%';\n\n\treturn `calc(${String(proportion)} * var(--_sonic-slider-travel) + var(--_sonic-slider-groove) / 2)`;\n}\n\nconst renderSlider = template(\n\t/* HTML */ `\n\t\t<div class=\"sonic-slider\" role=\"slider\" tabindex=\"0\">\n\t\t\t<div class=\"sonic-slider-scale\" aria-hidden=\"true\"></div>\n\t\t\t<div class=\"sonic-slider-notches\"></div>\n\t\t\t<div class=\"sonic-slider-groove\"></div>\n\t\t\t<div class=\"sonic-slider-modulation\"></div>\n\t\t\t<div class=\"sonic-slider-cap\"></div>\n\t\t\t<div class=\"sonic-slider-readout\" popover=\"manual\">\n\t\t\t\t<span></span>\n\t\t\t\t<input\n\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t\tclass=\"sonic-slider-entry\"\n\t\t\t\t\tenterkeyhint=\"done\"\n\t\t\t\t\thidden\n\t\t\t\t\tspellcheck=\"false\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t`,\n\tHTMLDivElement,\n);\n\nexport class SonicSlider extends SonicValueElement {\n\tstatic override readonly observedAttributes = [\n\t\t...SonicValueElement.observedAttributes,\n\t\t'modulation',\n\t\t'orientation',\n\t\t'scrub',\n\t\t'spring',\n\t];\n\n\t// fallow-ignore-next-line code-duplication -- one accessor pair per property\n\tget buffered(): Array<[number, number]> {\n\t\treturn this.#buffered.map(([start, end]) => [start, end]);\n\t}\n\n\tset buffered(regions: TimeRegions | undefined) {\n\t\tthis.#buffered = sortedRegions(regions);\n\t\tthis.render();\n\t}\n\n\tget groovePress(): 'jump' | 'none' {\n\t\treturn this.getAttribute('groove-press') === 'none' ? 'none' : 'jump';\n\t}\n\n\tset groovePress(gesture: 'jump' | 'none' | undefined) {\n\t\tthis.reflect('groove-press', gesture);\n\t}\n\n\tget modulation(): number {\n\t\treturn this.numberAttribute('modulation', 0);\n\t}\n\n\tset modulation(amount: number | undefined) {\n\t\tthis.reflect('modulation', amount);\n\t}\n\n\tget modulationValue(): number | undefined {\n\t\treturn this.#modulation.value();\n\t}\n\n\tset modulationValue(value: null | number | undefined) {\n\t\tthis.#modulation.write(value, this.isBound() ? this.mapping() : undefined);\n\t}\n\n\tget orientation(): 'horizontal' | 'vertical' {\n\t\treturn this.getAttribute('orientation') === 'vertical' ? 'vertical' : 'horizontal';\n\t}\n\n\tset orientation(direction: 'horizontal' | 'vertical' | undefined) {\n\t\tthis.reflect('orientation', direction);\n\t}\n\n\tget scrub(): boolean {\n\t\treturn this.hasAttribute('scrub');\n\t}\n\n\tset scrub(isScrubbing: boolean) {\n\t\tthis.reflect('scrub', isScrubbing);\n\t}\n\n\tget spring(): boolean {\n\t\treturn this.hasAttribute('spring');\n\t}\n\n\tset spring(isSpring: boolean) {\n\t\tthis.reflect('spring', isSpring);\n\t}\n\n\t#buffered: Array<[number, number]> = [];\n\n\treadonly #slider = renderSlider();\n\n\treadonly #modulation = createModulation(this.#slider, 'slider', (isModulated) => {\n\t\tthis.toggleState('modulated', isModulated);\n\t});\n\n\toverride connectedCallback(): void {\n\t\tthis.upgradeProperties(\n\t\t\t'buffered',\n\t\t\t'groovePress',\n\t\t\t'modulationValue',\n\t\t\t'modulation',\n\t\t\t'orientation',\n\t\t\t'scrub',\n\t\t\t'spring',\n\t\t);\n\t\tsuper.connectedCallback();\n\t}\n\n\tprotected connect(signal: AbortSignal): void {\n\t\tconst slider = this.#slider;\n\t\tconst cap = requireChild(slider, '.sonic-slider-cap', HTMLDivElement);\n\n\t\tbindScale(\n\t\t\tthis,\n\t\t\t{ control: slider, marks: requireChild(slider, '.sonic-slider-scale', HTMLDivElement) },\n\t\t\tsignal,\n\t\t);\n\t\tslider.addEventListener(\n\t\t\t'transitionend',\n\t\t\t(event) => {\n\t\t\t\tif (event.propertyName === '--_sonic-slider-value') this.toggleState('springing', false);\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t\tthis.bindHover(slider, signal, {\n\t\t\tcanShow: () => this.scrub && this.readout && this.orientation === 'horizontal',\n\t\t\tplace: () => {\n\t\t\t\tthis.#placeReadout(slider);\n\t\t\t},\n\t\t\tvalueAt: (event) => {\n\t\t\t\tconst axis = this.#axis(slider, cap);\n\t\t\t\tconst at = clampProportion((axis.position(event) - axis.startPx) / axis.travelPx);\n\t\t\t\tconst mapping = this.mapping();\n\n\t\t\t\treturn mapping.snap(mapping.valueAt(at));\n\t\t\t},\n\t\t});\n\t\tthis.render();\n\t\tthis.checkStyles(slider, 'slider.css');\n\t\tthis.bindGestures(slider, signal, (event) => {\n\t\t\tconst axis = this.#axis(slider, cap);\n\t\t\tif (event.target instanceof Node && cap.contains(event.target)) return axis;\n\n\t\t\tif (this.groovePress === 'none') return;\n\n\t\t\tthis.input(this.mapping().valueAt((axis.position(event) - axis.startPx) / axis.travelPx));\n\n\t\t\treturn axis;\n\t\t});\n\t}\n\n\tprotected override controlOrientation(): 'horizontal' | 'vertical' {\n\t\treturn this.orientation;\n\t}\n\n\tprotected draw(): void {\n\t\tthis.#modulation.draw({\n\t\t\tmapping: this.mapping(),\n\t\t\tmodulation: this.modulation,\n\t\t\torigin: this.originValue(),\n\t\t\tvalue: this.value,\n\t\t});\n\t\tthis.#renderBuffered(this.#slider);\n\t\tthis.#renderScrub(this.#slider);\n\t\tthis.#placeReadout(this.#slider);\n\t}\n\n\tprotected override focusTarget(): HTMLElement {\n\t\treturn this.#slider;\n\t}\n\n\tprotected override heldWrite(next: number): void {\n\t\tsuper.heldWrite(next);\n\t\tif (this.scrub) this.render();\n\t}\n\n\tprotected override holdChanged(): void {\n\t\tif (this.scrub) this.render();\n\t}\n\n\tprotected override scrubsKeyRepeat(): boolean {\n\t\treturn this.scrub;\n\t}\n\n\tprotected override springTarget(): number | undefined {\n\t\treturn this.spring ? this.originValue() : undefined;\n\t}\n\n\t#axis(slider: HTMLElement, cap: HTMLElement): SliderAxis {\n\t\tconst box = slider.getBoundingClientRect();\n\t\tconst capBox = cap.getBoundingClientRect();\n\n\t\treturn this.orientation === 'vertical'\n\t\t\t? {\n\t\t\t\t\tposition: (event) => -event.clientY,\n\t\t\t\t\tstartPx: capBox.height / 2 - box.bottom,\n\t\t\t\t\ttravelPx: Math.max(1, box.height - capBox.height),\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tposition: (event) => event.clientX,\n\t\t\t\t\tstartPx: box.left + capBox.width / 2,\n\t\t\t\t\ttravelPx: Math.max(1, box.width - capBox.width),\n\t\t\t\t};\n\t}\n\n\t#placeReadout(slider: HTMLElement): void {\n\t\tif (!this.scrub) {\n\t\t\tslider.style.removeProperty('--_sonic-slider-readout-value');\n\t\t\treturn;\n\t\t}\n\n\t\tslider.style.setProperty(\n\t\t\t'--_sonic-slider-readout-value',\n\t\t\tString(this.mapping().proportionOf(this.readoutValue())),\n\t\t);\n\t}\n\n\t#renderBuffered(slider: HTMLElement): void {\n\t\tconst buffered = this.#buffered;\n\n\t\tif (buffered.length === 0) {\n\t\t\tslider.style.removeProperty('--_sonic-slider-buffered-regions');\n\t\t\treturn;\n\t\t}\n\n\t\tconst { proportionOf } = this.mapping();\n\t\tconst stops = buffered.flatMap(([start, end]) => {\n\t\t\tconst from = grooveStop(proportionOf(Math.min(start, end)));\n\t\t\tconst to = grooveStop(proportionOf(Math.max(start, end)));\n\n\t\t\treturn [\n\t\t\t\t`transparent ${from}`,\n\t\t\t\t`var(--_sonic-slider-buffered) ${from} ${to}`,\n\t\t\t\t`transparent ${to}`,\n\t\t\t];\n\t\t});\n\n\t\tslider.style.setProperty(\n\t\t\t'--_sonic-slider-buffered-regions',\n\t\t\t`linear-gradient(var(--_sonic-slider-toward), ${stops.join(', ')})`,\n\t\t);\n\t}\n\n\t#renderScrub(slider: HTMLElement): void {\n\t\tconst { style } = slider;\n\t\tconst { proportionOf } = this.mapping();\n\t\tconst isHeld = this.scrub && this.heldFrom() !== undefined;\n\t\tconst played = proportionOf(this.playback());\n\t\tconst scrubbed = proportionOf(this.value);\n\n\t\tif (isHeld) style.setProperty('--_sonic-slider-played', String(played));\n\t\telse style.removeProperty('--_sonic-slider-played');\n\n\t\tif (played === scrubbed || !isHeld || !this.isRevealed()) {\n\t\t\tstyle.removeProperty('--_sonic-slider-scrub-region');\n\t\t\treturn;\n\t\t}\n\n\t\tconst from = grooveStop(Math.min(played, scrubbed));\n\t\tconst to = grooveStop(Math.max(played, scrubbed));\n\n\t\tstyle.setProperty(\n\t\t\t'--_sonic-slider-scrub-region',\n\t\t\t`linear-gradient(var(--_sonic-slider-toward), transparent ${from}, var(--_sonic-slider-scrub) ${from} ${to}, transparent ${to})`,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"slider.js","names":[],"sources":["../../../src/elements/slider.ts"],"sourcesContent":["import type { ValueAxis } from '#elements/value-gestures.ts';\nimport type { TimeRegions } from '#lib/time-regions.ts';\n\nimport { createModulation } from '#elements/modulation.ts';\nimport { bindScale } from '#elements/scale.ts';\nimport { SonicValueElement } from '#elements/value-element.ts';\nimport { clampProportion } from '#lib/math.ts';\nimport { requireChild, template } from '#lib/render.ts';\nimport { sortedRegions } from '#lib/time-regions.ts';\n\ndeclare global {\n\tinterface HTMLElementTagNameMap {\n\t\t'sonic-slider': SonicSlider;\n\t}\n}\n\ninterface SliderAxis extends ValueAxis {\n\tstartPx: number;\n}\n\nfunction grooveStop(proportion: number): string {\n\tif (proportion <= 0) return '0%';\n\tif (proportion >= 1) return '100%';\n\n\treturn `calc(${String(proportion)} * var(--_sonic-slider-travel) + var(--_sonic-slider-groove) / 2)`;\n}\n\nconst renderSlider = template(\n\t/* HTML */ `\n\t\t<div class=\"sonic-slider\" role=\"slider\" tabindex=\"0\">\n\t\t\t<div class=\"sonic-slider-scale\" aria-hidden=\"true\"></div>\n\t\t\t<div class=\"sonic-slider-notches\"></div>\n\t\t\t<div class=\"sonic-slider-groove\"></div>\n\t\t\t<div class=\"sonic-slider-modulation\"></div>\n\t\t\t<div class=\"sonic-slider-cap\"></div>\n\t\t\t<div class=\"sonic-slider-readout\" popover=\"manual\">\n\t\t\t\t<span></span>\n\t\t\t\t<input\n\t\t\t\t\tautocomplete=\"off\"\n\t\t\t\t\tclass=\"sonic-slider-entry\"\n\t\t\t\t\tenterkeyhint=\"done\"\n\t\t\t\t\thidden\n\t\t\t\t\tspellcheck=\"false\"\n\t\t\t\t\ttype=\"text\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</div>\n\t`,\n\tHTMLDivElement,\n);\n\nexport class SonicSlider extends SonicValueElement {\n\tstatic override readonly observedAttributes = [\n\t\t...SonicValueElement.observedAttributes,\n\t\t'modulation',\n\t\t'orientation',\n\t\t'scrub',\n\t\t'spring',\n\t];\n\n\t// fallow-ignore-next-line code-duplication -- one accessor pair per property\n\tget buffered(): Array<[number, number]> {\n\t\treturn this.#buffered.map(([start, end]) => [start, end]);\n\t}\n\n\tset buffered(regions: TimeRegions | undefined) {\n\t\tthis.#buffered = sortedRegions(regions);\n\t\tthis.render();\n\t}\n\n\tget groovePress(): 'jump' | 'none' {\n\t\treturn this.getAttribute('groove-press') === 'none' ? 'none' : 'jump';\n\t}\n\n\tset groovePress(gesture: 'jump' | 'none' | undefined) {\n\t\tthis.reflect('groove-press', gesture);\n\t}\n\n\tget modulation(): number {\n\t\treturn this.numberAttribute('modulation', 0);\n\t}\n\n\tset modulation(amount: number | undefined) {\n\t\tthis.reflect('modulation', amount);\n\t}\n\n\tget modulationValue(): number | undefined {\n\t\treturn this.#modulation.value();\n\t}\n\n\tset modulationValue(value: null | number | undefined) {\n\t\tthis.#modulation.write(value, this.isBound() ? this.mapping() : undefined);\n\t}\n\n\tget orientation(): 'horizontal' | 'vertical' {\n\t\treturn this.getAttribute('orientation') === 'vertical' ? 'vertical' : 'horizontal';\n\t}\n\n\tset orientation(direction: 'horizontal' | 'vertical' | undefined) {\n\t\tthis.reflect('orientation', direction);\n\t}\n\n\tget scrub(): boolean {\n\t\treturn this.hasAttribute('scrub');\n\t}\n\n\tset scrub(isScrubbing: boolean) {\n\t\tthis.reflect('scrub', isScrubbing);\n\t}\n\n\tget spring(): boolean {\n\t\treturn this.hasAttribute('spring');\n\t}\n\n\tset spring(isSpring: boolean) {\n\t\tthis.reflect('spring', isSpring);\n\t}\n\n\t#buffered: Array<[number, number]> = [];\n\n\treadonly #slider = renderSlider();\n\n\treadonly #modulation = createModulation(this.#slider, 'slider', (isModulated) => {\n\t\tthis.toggleState('modulated', isModulated);\n\t});\n\n\toverride connectedCallback(): void {\n\t\tthis.upgradeProperties(\n\t\t\t'buffered',\n\t\t\t'groovePress',\n\t\t\t'modulationValue',\n\t\t\t'modulation',\n\t\t\t'orientation',\n\t\t\t'scrub',\n\t\t\t'spring',\n\t\t);\n\t\tsuper.connectedCallback();\n\t}\n\n\tprotected connect(signal: AbortSignal): void {\n\t\tconst slider = this.#slider;\n\t\tconst cap = requireChild(slider, '.sonic-slider-cap', HTMLDivElement);\n\n\t\tbindScale(\n\t\t\tthis,\n\t\t\t{ control: slider, marks: requireChild(slider, '.sonic-slider-scale', HTMLDivElement) },\n\t\t\tsignal,\n\t\t);\n\t\tslider.addEventListener(\n\t\t\t'transitionend',\n\t\t\t(event) => {\n\t\t\t\tif (event.propertyName === '--_sonic-slider-value') this.toggleState('springing', false);\n\t\t\t},\n\t\t\t{ signal },\n\t\t);\n\t\tthis.bindHover(slider, signal, {\n\t\t\tcanShow: () => this.scrub && this.orientation === 'horizontal',\n\t\t\tplace: () => {\n\t\t\t\tthis.#placeReadout(slider);\n\t\t\t},\n\t\t\tvalueAt: (event) => {\n\t\t\t\tconst axis = this.#axis(slider, cap);\n\t\t\t\tconst at = clampProportion((axis.position(event) - axis.startPx) / axis.travelPx);\n\t\t\t\tconst mapping = this.mapping();\n\n\t\t\t\treturn mapping.snap(mapping.valueAt(at));\n\t\t\t},\n\t\t});\n\t\tthis.render();\n\t\tthis.checkStyles(slider, 'slider.css');\n\t\tthis.bindGestures(slider, signal, (event) => {\n\t\t\tconst axis = this.#axis(slider, cap);\n\t\t\tif (event.target instanceof Node && cap.contains(event.target)) return axis;\n\n\t\t\tif (this.groovePress === 'none') return;\n\n\t\t\tthis.input(this.mapping().valueAt((axis.position(event) - axis.startPx) / axis.travelPx));\n\n\t\t\treturn axis;\n\t\t});\n\t}\n\n\tprotected override controlOrientation(): 'horizontal' | 'vertical' {\n\t\treturn this.orientation;\n\t}\n\n\tprotected draw(): void {\n\t\tthis.#modulation.draw({\n\t\t\tmapping: this.mapping(),\n\t\t\tmodulation: this.modulation,\n\t\t\torigin: this.originValue(),\n\t\t\tvalue: this.value,\n\t\t});\n\t\tthis.#renderBuffered(this.#slider);\n\t\tthis.#renderScrub(this.#slider);\n\t\tthis.#placeReadout(this.#slider);\n\t}\n\n\tprotected override focusTarget(): HTMLElement {\n\t\treturn this.#slider;\n\t}\n\n\tprotected override heldWrite(next: number): void {\n\t\tsuper.heldWrite(next);\n\t\tif (this.scrub) this.render();\n\t}\n\n\tprotected override holdChanged(): void {\n\t\tif (this.scrub) this.render();\n\t}\n\n\tprotected override scrubsKeyRepeat(): boolean {\n\t\treturn this.scrub;\n\t}\n\n\tprotected override springTarget(): number | undefined {\n\t\treturn this.spring ? this.originValue() : undefined;\n\t}\n\n\t#axis(slider: HTMLElement, cap: HTMLElement): SliderAxis {\n\t\tconst box = slider.getBoundingClientRect();\n\t\tconst capBox = cap.getBoundingClientRect();\n\n\t\treturn this.orientation === 'vertical'\n\t\t\t? {\n\t\t\t\t\tposition: (event) => -event.clientY,\n\t\t\t\t\tstartPx: capBox.height / 2 - box.bottom,\n\t\t\t\t\ttravelPx: Math.max(1, box.height - capBox.height),\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tposition: (event) => event.clientX,\n\t\t\t\t\tstartPx: box.left + capBox.width / 2,\n\t\t\t\t\ttravelPx: Math.max(1, box.width - capBox.width),\n\t\t\t\t};\n\t}\n\n\t#placeReadout(slider: HTMLElement): void {\n\t\tif (!this.scrub) {\n\t\t\tslider.style.removeProperty('--_sonic-slider-readout-value');\n\t\t\treturn;\n\t\t}\n\n\t\tslider.style.setProperty(\n\t\t\t'--_sonic-slider-readout-value',\n\t\t\tString(this.mapping().proportionOf(this.readoutValue())),\n\t\t);\n\t}\n\n\t#renderBuffered(slider: HTMLElement): void {\n\t\tconst buffered = this.#buffered;\n\n\t\tif (buffered.length === 0) {\n\t\t\tslider.style.removeProperty('--_sonic-slider-buffered-regions');\n\t\t\treturn;\n\t\t}\n\n\t\tconst { proportionOf } = this.mapping();\n\t\tconst stops = buffered.flatMap(([start, end]) => {\n\t\t\tconst from = grooveStop(proportionOf(Math.min(start, end)));\n\t\t\tconst to = grooveStop(proportionOf(Math.max(start, end)));\n\n\t\t\treturn [\n\t\t\t\t`transparent ${from}`,\n\t\t\t\t`var(--_sonic-slider-buffered) ${from} ${to}`,\n\t\t\t\t`transparent ${to}`,\n\t\t\t];\n\t\t});\n\n\t\tslider.style.setProperty(\n\t\t\t'--_sonic-slider-buffered-regions',\n\t\t\t`linear-gradient(var(--_sonic-slider-toward), ${stops.join(', ')})`,\n\t\t);\n\t}\n\n\t#renderScrub(slider: HTMLElement): void {\n\t\tconst { style } = slider;\n\t\tconst { proportionOf } = this.mapping();\n\t\tconst isHeld = this.scrub && this.heldFrom() !== undefined;\n\t\tconst played = proportionOf(this.playback());\n\t\tconst scrubbed = proportionOf(this.value);\n\n\t\tif (isHeld) style.setProperty('--_sonic-slider-played', String(played));\n\t\telse style.removeProperty('--_sonic-slider-played');\n\n\t\tif (played === scrubbed || !isHeld || !this.isRevealed()) {\n\t\t\tstyle.removeProperty('--_sonic-slider-scrub-region');\n\t\t\treturn;\n\t\t}\n\n\t\tconst from = grooveStop(Math.min(played, scrubbed));\n\t\tconst to = grooveStop(Math.max(played, scrubbed));\n\n\t\tstyle.setProperty(\n\t\t\t'--_sonic-slider-scrub-region',\n\t\t\t`linear-gradient(var(--_sonic-slider-toward), transparent ${from}, var(--_sonic-slider-scrub) ${from} ${to}, transparent ${to})`,\n\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -49,6 +49,7 @@ export declare class SonicSpectrum extends SonicDisplayElement<Colour, Numeric>
|
|
|
49
49
|
readonly hotFrom: "--_sonic-spectrum-hot-from";
|
|
50
50
|
};
|
|
51
51
|
protected readonly sheet = "spectrum.css";
|
|
52
|
+
protected readonly sizeProperty = "--_sonic-spectrum-size";
|
|
52
53
|
connectedCallback(): void;
|
|
53
54
|
resetPeak(): void;
|
|
54
55
|
protected paint(context: CanvasRenderingContext2D, { frameMs, isDirty, look, size }: SurfaceFrame<Colour, never, Numeric>): void;
|